Changeset View
Changeset View
Standalone View
Standalone View
branches/5.3.x/core/ckeditor/ckfinder/plugins/zip/plugin.php
Property | Old Value | New Value |
---|---|---|
svn:eol-style | null | LF |
svn:keywords | null | Id |
<?php | <?php | ||||
/* | /* | ||||
* CKFinder | * CKFinder | ||||
* ======== | * ======== | ||||
* http://cksource.com/ckfinder | * http://cksource.com/ckfinder | ||||
* Copyright (C) 2007-2013, CKSource - Frederico Knabben. All rights reserved. | * Copyright (C) 2007-2013, CKSource - Frederico Knabben. All rights reserved. | ||||
* | * | ||||
* The software, this file and its contents are subject to the CKFinder | * The software, this file and its contents are subject to the CKFinder | ||||
* License. Please read the license.txt file before using, installing, copying, | * License. Please read the license.txt file before using, installing, copying, | ||||
* modifying or distribute this file or part of its contents. The contents of | * modifying or distribute this file or part of its contents. The contents of | ||||
* this file is part of the Source Code of CKFinder. | * this file is part of the Source Code of CKFinder. | ||||
* | * | ||||
* CKFinder extension: provides commands to add files into a zip archive, or extract contents from a zip. | * CKFinder extension: provides commands to add files into a zip archive, or extract contents from a zip. | ||||
*/ | */ | ||||
if (!defined('IN_CKFINDER')) exit; | if (!defined('IN_CKFINDER')) exit; | ||||
/** | /** | ||||
* Include base XML command handler | * Include base XML command handler | ||||
*/ | */ | ||||
require_once CKFINDER_CONNECTOR_LIB_DIR . "/CommandHandler/XmlCommandHandlerBase.php"; | require_once CKFINDER_CONNECTOR_LIB_DIR . "/CommandHandler/XmlCommandHandlerBase.php"; | ||||
class CKFinder_Connector_CommandHandler_Unzip extends CKFinder_Connector_CommandHandler_XmlCommandHandlerBase | class CKFinder_Connector_CommandHandler_Unzip extends CKFinder_Connector_CommandHandler_XmlCommandHandlerBase | ||||
{ | { | ||||
protected $filePath; | protected $filePath; | ||||
protected $skippedFilesNode; | protected $skippedFilesNode; | ||||
protected $_config; | protected $_config; | ||||
/** | /** | ||||
* Handle request and build XML | * Handle request and build XML | ||||
*/ | */ | ||||
protected function buildXml() | protected function buildXml() | ||||
{ | { | ||||
if (empty($_POST['CKFinderCommand']) || $_POST['CKFinderCommand'] != 'true') { | if (empty($_POST['CKFinderCommand']) || $_POST['CKFinderCommand'] != 'true') { | ||||
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_INVALID_REQUEST); | $this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_INVALID_REQUEST); | ||||
} | } | ||||
if (!extension_loaded('zip')) { | if (!extension_loaded('zip')) { | ||||
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_INVALID_COMMAND); | $this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_INVALID_COMMAND); | ||||
} | } | ||||
$this->checkConnector(); | $this->checkConnector(); | ||||
$this->checkRequest(); | $this->checkRequest(); | ||||
if ( !$this->_currentFolder->checkAcl(CKFINDER_CONNECTOR_ACL_FILE_UPLOAD)) { | if ( !$this->_currentFolder->checkAcl(CKFINDER_CONNECTOR_ACL_FILE_UPLOAD)) { | ||||
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_UNAUTHORIZED); | $this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_UNAUTHORIZED); | ||||
} | } | ||||
if (!isset($_POST["fileName"])) { | if (!isset($_POST["fileName"])) { | ||||
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_INVALID_NAME); | $this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_INVALID_NAME); | ||||
} | } | ||||
$fileName = CKFinder_Connector_Utils_FileSystem::convertToFilesystemEncoding($_POST["fileName"]); | $fileName = CKFinder_Connector_Utils_FileSystem::convertToFilesystemEncoding($_POST["fileName"]); | ||||
$resourceTypeInfo = $this->_currentFolder->getResourceTypeConfig(); | $resourceTypeInfo = $this->_currentFolder->getResourceTypeConfig(); | ||||
if (!$resourceTypeInfo->checkExtension($fileName)) { | if (!$resourceTypeInfo->checkExtension($fileName)) { | ||||
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_INVALID_EXTENSION); | $this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_INVALID_EXTENSION); | ||||
} | } | ||||
if (!CKFinder_Connector_Utils_FileSystem::checkFileName($fileName) || $resourceTypeInfo->checkIsHiddenFile($fileName)) { | if (!CKFinder_Connector_Utils_FileSystem::checkFileName($fileName) || $resourceTypeInfo->checkIsHiddenFile($fileName)) { | ||||
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_INVALID_REQUEST); | $this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_INVALID_REQUEST); | ||||
} | } | ||||
$filePath = CKFinder_Connector_Utils_FileSystem::combinePaths($this->_currentFolder->getServerPath(), $fileName); | $filePath = CKFinder_Connector_Utils_FileSystem::combinePaths($this->_currentFolder->getServerPath(), $fileName); | ||||
if (!file_exists($filePath) || !is_file($filePath)) { | if (!file_exists($filePath) || !is_file($filePath)) { | ||||
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_FILE_NOT_FOUND); | $this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_FILE_NOT_FOUND); | ||||
} | } | ||||
if (!is_writable(dirname($filePath))) { | if (!is_writable(dirname($filePath))) { | ||||
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_ACCESS_DENIED); | $this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_ACCESS_DENIED); | ||||
} | } | ||||
if ( strtolower(pathinfo($fileName, PATHINFO_EXTENSION)) !== 'zip'){ | if ( strtolower(pathinfo($fileName, PATHINFO_EXTENSION)) !== 'zip'){ | ||||
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_INVALID_EXTENSION); | $this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_INVALID_EXTENSION); | ||||
} | } | ||||
$zip = new ZipArchive(); | $zip = new ZipArchive(); | ||||
$result = $zip->open($filePath); | $result = $zip->open($filePath); | ||||
if ($result !== TRUE) { | if ($result !== TRUE) { | ||||
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_UNKNOWN); | $this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_UNKNOWN); | ||||
} | } | ||||
$this->zip = $zip; | $this->zip = $zip; | ||||
$this->filePath = $filePath; | $this->filePath = $filePath; | ||||
$this->_config =& CKFinder_Connector_Core_Factory::getInstance("Core_Config"); | $this->_config =& CKFinder_Connector_Core_Factory::getInstance("Core_Config"); | ||||
// list of unzipped nodes | // list of unzipped nodes | ||||
$this->unzippedNodes = new CKFinder_Connector_Utils_XmlNode("UnzippedFiles"); | $this->unzippedNodes = new CKFinder_Connector_Utils_XmlNode("UnzippedFiles"); | ||||
// list of files which could not be unzipped | // list of files which could not be unzipped | ||||
$this->skippedFilesNode = new CKFinder_Connector_Utils_XmlNode("Errors"); | $this->skippedFilesNode = new CKFinder_Connector_Utils_XmlNode("Errors"); | ||||
$this->errorCode = CKFINDER_CONNECTOR_ERROR_NONE; | $this->errorCode = CKFINDER_CONNECTOR_ERROR_NONE; | ||||
} | } | ||||
/** | /** | ||||
* Check one file for security reasons | * Check one file for security reasons | ||||
* | * | ||||
* @param object $filePathInfo | * @param object $filePathInfo | ||||
* @param string $originalFileName | * @param string $originalFileName | ||||
* @return mixed bool(false) - if security checks fails. Otherwise string - ralative zip archive path with secured filename. | * @return mixed bool(false) - if security checks fails. Otherwise string - ralative zip archive path with secured filename. | ||||
*/ | */ | ||||
protected function checkOneFile($filePathInfo, $originalFileName ) | protected function checkOneFile($filePathInfo, $originalFileName ) | ||||
{ | { | ||||
$resourceTypeInfo = $this->_currentFolder->getResourceTypeConfig(); | $resourceTypeInfo = $this->_currentFolder->getResourceTypeConfig(); | ||||
// checked if it is a folder | // checked if it is a folder | ||||
$fileStat = $this->zip->statName($originalFileName); | $fileStat = $this->zip->statName($originalFileName); | ||||
if ( empty($filePathInfo['extension']) && empty($fileStat['size']) ){ | if ( empty($filePathInfo['extension']) && empty($fileStat['size']) ){ | ||||
$sNewFolderName = CKFinder_Connector_Utils_FileSystem::convertToFilesystemEncoding(rtrim($fileStat['name'],'/')); | $sNewFolderName = CKFinder_Connector_Utils_FileSystem::convertToFilesystemEncoding(rtrim($fileStat['name'],'/')); | ||||
if ($this->_config->forceAscii()) { | if ($this->_config->forceAscii()) { | ||||
$sNewFolderName = CKFinder_Connector_Utils_FileSystem::convertToAscii($sNewFolderName); | $sNewFolderName = CKFinder_Connector_Utils_FileSystem::convertToAscii($sNewFolderName); | ||||
} | } | ||||
if (!CKFinder_Connector_Utils_FileSystem::checkFolderPath($sNewFolderName) || $resourceTypeInfo->checkIsHiddenFolder($sNewFolderName)) { | if (!CKFinder_Connector_Utils_FileSystem::checkFolderPath($sNewFolderName) || $resourceTypeInfo->checkIsHiddenFolder($sNewFolderName)) { | ||||
$this->errorCode = CKFINDER_CONNECTOR_ERROR_INVALID_NAME; | $this->errorCode = CKFINDER_CONNECTOR_ERROR_INVALID_NAME; | ||||
$this->appendErrorNode($this->skippedFilesNode, $this->errorCode, $originalFileName); | $this->appendErrorNode($this->skippedFilesNode, $this->errorCode, $originalFileName); | ||||
return false; | return false; | ||||
} | } | ||||
if (!is_writeable($this->_currentFolder->getServerPath())) { | if (!is_writeable($this->_currentFolder->getServerPath())) { | ||||
$this->errorCode = CKFINDER_CONNECTOR_ERROR_ACCESS_DENIED; | $this->errorCode = CKFINDER_CONNECTOR_ERROR_ACCESS_DENIED; | ||||
$this->appendErrorNode($this->skippedFilesNode, $this->errorCode, $originalFileName); | $this->appendErrorNode($this->skippedFilesNode, $this->errorCode, $originalFileName); | ||||
return false; | return false; | ||||
} | } | ||||
return $originalFileName; | return $originalFileName; | ||||
} | } | ||||
$fileName = CKFinder_Connector_Utils_FileSystem::convertToFilesystemEncoding($filePathInfo['basename']); | $fileName = CKFinder_Connector_Utils_FileSystem::convertToFilesystemEncoding($filePathInfo['basename']); | ||||
$sFileName = CKFinder_Connector_Utils_FileSystem::secureFileName($fileName); | $sFileName = CKFinder_Connector_Utils_FileSystem::secureFileName($fileName); | ||||
// max file size | // max file size | ||||
$maxSize = $resourceTypeInfo->getMaxSize(); | $maxSize = $resourceTypeInfo->getMaxSize(); | ||||
if ( $maxSize && $fileStat['size'] > $maxSize ) | if ( $maxSize && $fileStat['size'] > $maxSize ) | ||||
{ | { | ||||
$this->errorCode = CKFINDER_CONNECTOR_ERROR_UPLOADED_TOO_BIG; | $this->errorCode = CKFINDER_CONNECTOR_ERROR_UPLOADED_TOO_BIG; | ||||
$this->appendErrorNode($this->skippedFilesNode, $this->errorCode, $originalFileName); | $this->appendErrorNode($this->skippedFilesNode, $this->errorCode, $originalFileName); | ||||
return false; | return false; | ||||
} | } | ||||
// extension | // extension | ||||
if ( !$resourceTypeInfo->checkExtension($sFileName) ) | if ( !$resourceTypeInfo->checkExtension($sFileName) ) | ||||
{ | { | ||||
$this->errorCode = CKFINDER_CONNECTOR_ERROR_INVALID_EXTENSION; | $this->errorCode = CKFINDER_CONNECTOR_ERROR_INVALID_EXTENSION; | ||||
$this->appendErrorNode($this->skippedFilesNode, $this->errorCode, $originalFileName); | $this->appendErrorNode($this->skippedFilesNode, $this->errorCode, $originalFileName); | ||||
return false; | return false; | ||||
} | } | ||||
// hidden file | // hidden file | ||||
if ( !CKFinder_Connector_Utils_FileSystem::checkFileName($sFileName) || $resourceTypeInfo->checkIsHiddenFile($sFileName) ){ | if ( !CKFinder_Connector_Utils_FileSystem::checkFileName($sFileName) || $resourceTypeInfo->checkIsHiddenFile($sFileName) ){ | ||||
$this->errorCode = CKFINDER_CONNECTOR_ERROR_INVALID_REQUEST; | $this->errorCode = CKFINDER_CONNECTOR_ERROR_INVALID_REQUEST; | ||||
$this->appendErrorNode($this->skippedFilesNode, $this->errorCode, $originalFileName); | $this->appendErrorNode($this->skippedFilesNode, $this->errorCode, $originalFileName); | ||||
return false; | return false; | ||||
} | } | ||||
// unpack file to tmp dir for detecting html and valid image | // unpack file to tmp dir for detecting html and valid image | ||||
$dir = CKFinder_Connector_Utils_FileSystem::getTmpDir().'/'; | $dir = CKFinder_Connector_Utils_FileSystem::getTmpDir().'/'; | ||||
if ( file_exists($dir.$sFileName) && !CKFinder_Connector_Utils_FileSystem::unlink($dir.$sFileName) ){ | if ( file_exists($dir.$sFileName) && !CKFinder_Connector_Utils_FileSystem::unlink($dir.$sFileName) ){ | ||||
$this->errorCode = CKFINDER_CONNECTOR_ERROR_INVALID_REQUEST; | $this->errorCode = CKFINDER_CONNECTOR_ERROR_INVALID_REQUEST; | ||||
$this->appendErrorNode($this->skippedFilesNode, $this->errorCode, $originalFileName); | $this->appendErrorNode($this->skippedFilesNode, $this->errorCode, $originalFileName); | ||||
return false; | return false; | ||||
} | } | ||||
if ( copy('zip://'.$this->filePath.'#'.$originalFileName, $dir.$sFileName) ) | if ( copy('zip://'.$this->filePath.'#'.$originalFileName, $dir.$sFileName) ) | ||||
{ | { | ||||
// html extensions | // html extensions | ||||
$htmlExtensions = $this->_config->getHtmlExtensions(); | $htmlExtensions = $this->_config->getHtmlExtensions(); | ||||
$sExtension = CKFinder_Connector_Utils_FileSystem::getExtension( $dir.$sFileName ); | $sExtension = CKFinder_Connector_Utils_FileSystem::getExtension( $dir.$sFileName ); | ||||
if ( $htmlExtensions | if ( $htmlExtensions | ||||
&& !CKFinder_Connector_Utils_Misc::inArrayCaseInsensitive( $sExtension, $htmlExtensions ) | && !CKFinder_Connector_Utils_Misc::inArrayCaseInsensitive( $sExtension, $htmlExtensions ) | ||||
&& CKFinder_Connector_Utils_FileSystem::detectHtml($dir.$sFileName) === true ) | && CKFinder_Connector_Utils_FileSystem::detectHtml($dir.$sFileName) === true ) | ||||
{ | { | ||||
$this->errorCode = CKFINDER_CONNECTOR_ERROR_UPLOADED_INVALID; | $this->errorCode = CKFINDER_CONNECTOR_ERROR_UPLOADED_INVALID; | ||||
$this->appendErrorNode($this->skippedFilesNode, $this->errorCode, $originalFileName); | $this->appendErrorNode($this->skippedFilesNode, $this->errorCode, $originalFileName); | ||||
return false; | return false; | ||||
} | } | ||||
// proper image | // proper image | ||||
$secureImageUploads = $this->_config->getSecureImageUploads(); | $secureImageUploads = $this->_config->getSecureImageUploads(); | ||||
if ( $secureImageUploads | if ( $secureImageUploads | ||||
&& ( $isImageValid = CKFinder_Connector_Utils_FileSystem::isImageValid($dir.$sFileName, $sExtension) ) === false ) | && ( $isImageValid = CKFinder_Connector_Utils_FileSystem::isImageValid($dir.$sFileName, $sExtension) ) === false ) | ||||
{ | { | ||||
$this->errorCode = CKFINDER_CONNECTOR_ERROR_UPLOADED_INVALID; | $this->errorCode = CKFINDER_CONNECTOR_ERROR_UPLOADED_INVALID; | ||||
$this->appendErrorNode($this->skippedFilesNode, $this->errorCode, $originalFileName); | $this->appendErrorNode($this->skippedFilesNode, $this->errorCode, $originalFileName); | ||||
return false; | return false; | ||||
} | } | ||||
} | } | ||||
$sDirName = ($filePathInfo['dirname'] != '.')? $filePathInfo['dirname'].'/' : ''; | $sDirName = ($filePathInfo['dirname'] != '.')? $filePathInfo['dirname'].'/' : ''; | ||||
return $sDirName.$sFileName; | return $sDirName.$sFileName; | ||||
} | } | ||||
/** | /** | ||||
* Add error node to the list | * Add error node to the list | ||||
* @param obj $oErrorsNode | * @param obj $oErrorsNode | ||||
* @param int $errorCode | * @param int $errorCode | ||||
* @param string $name | * @param string $name | ||||
* @param string $type | * @param string $type | ||||
* @param string $path | * @param string $path | ||||
*/ | */ | ||||
protected function appendErrorNode($oErrorsNode, $errorCode=0, $name, $type=null, $path=null) | protected function appendErrorNode($oErrorsNode, $errorCode=0, $name, $type=null, $path=null) | ||||
{ | { | ||||
$oErrorNode = new CKFinder_Connector_Utils_XmlNode("Error"); | $oErrorNode = new CKFinder_Connector_Utils_XmlNode("Error"); | ||||
$oErrorNode->addAttribute("code", $errorCode); | $oErrorNode->addAttribute("code", $errorCode); | ||||
$oErrorNode->addAttribute("name", CKFinder_Connector_Utils_FileSystem::convertToConnectorEncoding($name)); | $oErrorNode->addAttribute("name", CKFinder_Connector_Utils_FileSystem::convertToConnectorEncoding($name)); | ||||
if ( $type ){ | if ( $type ){ | ||||
$oErrorNode->addAttribute("type", $type); | $oErrorNode->addAttribute("type", $type); | ||||
} | } | ||||
if ( $path ){ | if ( $path ){ | ||||
$oErrorNode->addAttribute("folder", $path); | $oErrorNode->addAttribute("folder", $path); | ||||
} | } | ||||
$oErrorsNode->addChild($oErrorNode); | $oErrorsNode->addChild($oErrorNode); | ||||
} | } | ||||
/** | /** | ||||
* Add unzipped node to the list | * Add unzipped node to the list | ||||
* @param obj $oUnzippedNodes | * @param obj $oUnzippedNodes | ||||
* @param string $name | * @param string $name | ||||
* @param string $action | * @param string $action | ||||
*/ | */ | ||||
protected function appendUnzippedNode($oUnzippedNodes, $name, $action='ok') | protected function appendUnzippedNode($oUnzippedNodes, $name, $action='ok') | ||||
{ | { | ||||
$oUnzippedNode = new CKFinder_Connector_Utils_XmlNode("File"); | $oUnzippedNode = new CKFinder_Connector_Utils_XmlNode("File"); | ||||
$oUnzippedNode->addAttribute("name", CKFinder_Connector_Utils_FileSystem::convertToConnectorEncoding($name)); | $oUnzippedNode->addAttribute("name", CKFinder_Connector_Utils_FileSystem::convertToConnectorEncoding($name)); | ||||
$oUnzippedNode->addAttribute("action", $action ); | $oUnzippedNode->addAttribute("action", $action ); | ||||
$oUnzippedNodes->addChild($oUnzippedNode); | $oUnzippedNodes->addChild($oUnzippedNode); | ||||
} | } | ||||
/** | /** | ||||
* Extract one file from zip archive | * Extract one file from zip archive | ||||
* | * | ||||
* @param string $extractPath | * @param string $extractPath | ||||
* @param string $extractClientPath | * @param string $extractClientPath | ||||
* @param array $filePathInfo | * @param array $filePathInfo | ||||
* @param string $sFileName | * @param string $sFileName | ||||
* @param string $originalFileName | * @param string $originalFileName | ||||
*/ | */ | ||||
protected function extractTo($extractPath, $extractClientPath, $filePathInfo, $sFileName, $originalFileName) | protected function extractTo($extractPath, $extractClientPath, $filePathInfo, $sFileName, $originalFileName) | ||||
{ | { | ||||
$sfilePathInfo = pathinfo($extractPath.$sFileName); | $sfilePathInfo = pathinfo($extractPath.$sFileName); | ||||
$extractClientPathDir = $filePathInfo['dirname']; | $extractClientPathDir = $filePathInfo['dirname']; | ||||
if ( $filePathInfo['dirname'] == '.' ){ | if ( $filePathInfo['dirname'] == '.' ){ | ||||
$extractClientPathDir = ''; | $extractClientPathDir = ''; | ||||
} | } | ||||
$folderPath = CKFinder_Connector_Utils_FileSystem::combinePaths($extractClientPath,$extractClientPathDir); | $folderPath = CKFinder_Connector_Utils_FileSystem::combinePaths($extractClientPath,$extractClientPathDir); | ||||
$_aclConfig = $this->_config->getAccessControlConfig(); | $_aclConfig = $this->_config->getAccessControlConfig(); | ||||
$aclMask = $_aclConfig->getComputedMask($this->_currentFolder->getResourceTypeName(),$folderPath); | $aclMask = $_aclConfig->getComputedMask($this->_currentFolder->getResourceTypeName(),$folderPath); | ||||
$canCreateFolder = (($aclMask & CKFINDER_CONNECTOR_ACL_FOLDER_CREATE ) == CKFINDER_CONNECTOR_ACL_FOLDER_CREATE ); | $canCreateFolder = (($aclMask & CKFINDER_CONNECTOR_ACL_FOLDER_CREATE ) == CKFINDER_CONNECTOR_ACL_FOLDER_CREATE ); | ||||
// create sub-directory of zip archive | // create sub-directory of zip archive | ||||
if ( empty($sfilePathInfo['extension']) ) | if ( empty($sfilePathInfo['extension']) ) | ||||
{ | { | ||||
$fileStat = $this->zip->statName($originalFileName); | $fileStat = $this->zip->statName($originalFileName); | ||||
$isDir = false; | $isDir = false; | ||||
if ( $fileStat && empty($fileStat['size']) ){ | if ( $fileStat && empty($fileStat['size']) ){ | ||||
$isDir = true; | $isDir = true; | ||||
} | } | ||||
if( !empty($sfilePathInfo['dirname']) && !empty($sfilePathInfo['basename']) && !file_exists($sfilePathInfo['dirname'].'/'.$sfilePathInfo['basename']) ) | if( !empty($sfilePathInfo['dirname']) && !empty($sfilePathInfo['basename']) && !file_exists($sfilePathInfo['dirname'].'/'.$sfilePathInfo['basename']) ) | ||||
{ | { | ||||
if ( !$canCreateFolder ){ | if ( !$canCreateFolder ){ | ||||
return; | return; | ||||
} | } | ||||
if ( $isDir ) { | if ( $isDir ) { | ||||
CKFinder_Connector_Utils_FileSystem::createDirectoryRecursively( $sfilePathInfo['dirname'].'/'.$sfilePathInfo['basename'] ); | CKFinder_Connector_Utils_FileSystem::createDirectoryRecursively( $sfilePathInfo['dirname'].'/'.$sfilePathInfo['basename'] ); | ||||
return; | return; | ||||
} else { | } else { | ||||
CKFinder_Connector_Utils_FileSystem::createDirectoryRecursively( $sfilePathInfo['dirname']); | CKFinder_Connector_Utils_FileSystem::createDirectoryRecursively( $sfilePathInfo['dirname']); | ||||
} | } | ||||
} else { | } else { | ||||
return; | return; | ||||
} | } | ||||
} | } | ||||
// extract file | // extract file | ||||
if ( !file_exists($sfilePathInfo['dirname']) ){ | if ( !file_exists($sfilePathInfo['dirname']) ){ | ||||
if ( !$canCreateFolder ){ | if ( !$canCreateFolder ){ | ||||
$this->errorCode = CKFINDER_CONNECTOR_ERROR_UNAUTHORIZED; | $this->errorCode = CKFINDER_CONNECTOR_ERROR_UNAUTHORIZED; | ||||
$this->appendErrorNode($this->skippedFilesNode, $this->errorCode, $originalFileName ); | $this->appendErrorNode($this->skippedFilesNode, $this->errorCode, $originalFileName ); | ||||
return; | return; | ||||
} | } | ||||
CKFinder_Connector_Utils_FileSystem::createDirectoryRecursively($sfilePathInfo['dirname']); | CKFinder_Connector_Utils_FileSystem::createDirectoryRecursively($sfilePathInfo['dirname']); | ||||
} | } | ||||
$isAuthorized = (($aclMask & CKFINDER_CONNECTOR_ACL_FILE_UPLOAD ) == CKFINDER_CONNECTOR_ACL_FILE_UPLOAD ); | $isAuthorized = (($aclMask & CKFINDER_CONNECTOR_ACL_FILE_UPLOAD ) == CKFINDER_CONNECTOR_ACL_FILE_UPLOAD ); | ||||
if ( !$isAuthorized ){ | if ( !$isAuthorized ){ | ||||
$this->errorCode = CKFINDER_CONNECTOR_ERROR_COPY_FAILED; | $this->errorCode = CKFINDER_CONNECTOR_ERROR_COPY_FAILED; | ||||
$this->appendErrorNode($this->skippedFilesNode, $this->errorCode, $originalFileName); | $this->appendErrorNode($this->skippedFilesNode, $this->errorCode, $originalFileName); | ||||
return; | return; | ||||
} | } | ||||
if ( copy('zip://'.$this->filePath.'#'.$originalFileName, $extractPath.$sFileName) ) | if ( copy('zip://'.$this->filePath.'#'.$originalFileName, $extractPath.$sFileName) ) | ||||
{ | { | ||||
$this->appendUnzippedNode($this->unzippedNodes,$originalFileName); | $this->appendUnzippedNode($this->unzippedNodes,$originalFileName); | ||||
// chmod extracted file | // chmod extracted file | ||||
if ( is_file($extractPath.$sFileName) && ( $perms = $this->_config->getChmodFiles()) ) | if ( is_file($extractPath.$sFileName) && ( $perms = $this->_config->getChmodFiles()) ) | ||||
{ | { | ||||
$oldumask = umask(0); | $oldumask = umask(0); | ||||
chmod( $extractPath.$sFileName, $perms ); | chmod( $extractPath.$sFileName, $perms ); | ||||
umask( $oldumask ); | umask( $oldumask ); | ||||
} | } | ||||
} | } | ||||
// file extraction failed, add to skipped | // file extraction failed, add to skipped | ||||
else | else | ||||
{ | { | ||||
$this->errorCode = CKFINDER_CONNECTOR_ERROR_COPY_FAILED; | $this->errorCode = CKFINDER_CONNECTOR_ERROR_COPY_FAILED; | ||||
$this->appendErrorNode($this->skippedFilesNode, $this->errorCode, $originalFileName); | $this->appendErrorNode($this->skippedFilesNode, $this->errorCode, $originalFileName); | ||||
} | } | ||||
} | } | ||||
} // end of CKFinder_Connector_CommandHandler_Unzip class | } // end of CKFinder_Connector_CommandHandler_Unzip class | ||||
class CKFinder_Connector_CommandHandler_UnzipHere extends CKFinder_Connector_CommandHandler_Unzip | class CKFinder_Connector_CommandHandler_UnzipHere extends CKFinder_Connector_CommandHandler_Unzip | ||||
{ | { | ||||
/** | /** | ||||
* Handle request and build XML | * Handle request and build XML | ||||
*/ | */ | ||||
protected function buildXml() | protected function buildXml() | ||||
{ | { | ||||
parent::buildXml(); | parent::buildXml(); | ||||
$checkedFiles = array(); | $checkedFiles = array(); | ||||
if ( !empty($_POST['files']) && is_array($_POST['files']) ){ | if ( !empty($_POST['files']) && is_array($_POST['files']) ){ | ||||
foreach ( $_POST['files'] as $file){ | foreach ( $_POST['files'] as $file){ | ||||
$checkedFiles[$file['name']] = $file; | $checkedFiles[$file['name']] = $file; | ||||
} | } | ||||
} | } | ||||
for ($i = 0; $i < $this->zip->numFiles; $i++) | for ($i = 0; $i < $this->zip->numFiles; $i++) | ||||
{ | { | ||||
$fileName = $this->zip->getNameIndex($i); | $fileName = $this->zip->getNameIndex($i); | ||||
if ( !empty($checkedFiles[$fileName]) && $checkedFiles[$fileName]['options'] == 'ok' ) | if ( !empty($checkedFiles[$fileName]) && $checkedFiles[$fileName]['options'] == 'ok' ) | ||||
{ | { | ||||
// file was sucessfully unzipped before | // file was sucessfully unzipped before | ||||
$this->appendUnzippedNode($this->unzippedNodes,$fileName); | $this->appendUnzippedNode($this->unzippedNodes,$fileName); | ||||
continue; | continue; | ||||
} | } | ||||
$filePathInfo = pathinfo($fileName); | $filePathInfo = pathinfo($fileName); | ||||
$fileType = 'File'; | $fileType = 'File'; | ||||
$fileStat = $this->zip->statName($i); | $fileStat = $this->zip->statName($i); | ||||
if ( empty($filePathInfo['extension']) && empty($fileStat['size']) ){ | if ( empty($filePathInfo['extension']) && empty($fileStat['size']) ){ | ||||
$fileType = 'Folder'; | $fileType = 'Folder'; | ||||
// check if we can create subfolder | // check if we can create subfolder | ||||
if ( !$this->_currentFolder->checkAcl( CKFINDER_CONNECTOR_ACL_FOLDER_CREATE ) ){ | if ( !$this->_currentFolder->checkAcl( CKFINDER_CONNECTOR_ACL_FOLDER_CREATE ) ){ | ||||
$this->errorCode = CKFINDER_CONNECTOR_ERROR_UNAUTHORIZED; | $this->errorCode = CKFINDER_CONNECTOR_ERROR_UNAUTHORIZED; | ||||
$this->appendErrorNode($this->skippedFilesNode, $this->errorCode, $fileName, $fileType); | $this->appendErrorNode($this->skippedFilesNode, $this->errorCode, $fileName, $fileType); | ||||
continue; | continue; | ||||
} | } | ||||
} | } | ||||
$extractPath = $this->_currentFolder->getServerPath(); | $extractPath = $this->_currentFolder->getServerPath(); | ||||
$extractClientPath = $this->_currentFolder->getClientPath(); | $extractClientPath = $this->_currentFolder->getClientPath(); | ||||
$sFileName = $this->checkOneFile( $filePathInfo, $fileName ); | $sFileName = $this->checkOneFile( $filePathInfo, $fileName ); | ||||
// security test failed, add to skipped | // security test failed, add to skipped | ||||
if ( false !== $sFileName ) | if ( false !== $sFileName ) | ||||
{ | { | ||||
if ( file_exists($extractPath.$sFileName) ) | if ( file_exists($extractPath.$sFileName) ) | ||||
{ | { | ||||
if ( !is_dir($extractPath.$sFileName) ) | if ( !is_dir($extractPath.$sFileName) ) | ||||
{ | { | ||||
// file was checked before | // file was checked before | ||||
if ( !empty($checkedFiles[$fileName]['options']) ) | if ( !empty($checkedFiles[$fileName]['options']) ) | ||||
{ | { | ||||
if ( $checkedFiles[$fileName]['options'] == 'autorename') | if ( $checkedFiles[$fileName]['options'] == 'autorename') | ||||
{ | { | ||||
$sFileName = CKFinder_Connector_Utils_FileSystem::autoRename($extractPath,$sFileName); | $sFileName = CKFinder_Connector_Utils_FileSystem::autoRename($extractPath,$sFileName); | ||||
$this->extractTo($extractPath,$extractClientPath,$filePathInfo,$sFileName,$fileName); | $this->extractTo($extractPath,$extractClientPath,$filePathInfo,$sFileName,$fileName); | ||||
} | } | ||||
elseif ( $checkedFiles[$fileName]['options'] == 'overwrite') | elseif ( $checkedFiles[$fileName]['options'] == 'overwrite') | ||||
{ | { | ||||
if ( !$this->_currentFolder->checkAcl( CKFINDER_CONNECTOR_ACL_FILE_DELETE ) ){ | if ( !$this->_currentFolder->checkAcl( CKFINDER_CONNECTOR_ACL_FILE_DELETE ) ){ | ||||
$this->errorCode = CKFINDER_CONNECTOR_ERROR_UNAUTHORIZED; | $this->errorCode = CKFINDER_CONNECTOR_ERROR_UNAUTHORIZED; | ||||
$this->appendErrorNode($this->skippedFilesNode, $this->errorCode, $fileName, $fileType); | $this->appendErrorNode($this->skippedFilesNode, $this->errorCode, $fileName, $fileType); | ||||
continue; | continue; | ||||
} | } | ||||
if (!CKFinder_Connector_Utils_FileSystem::unlink($extractPath.$sFileName)) | if (!CKFinder_Connector_Utils_FileSystem::unlink($extractPath.$sFileName)) | ||||
{ | { | ||||
$this->errorCode = CKFINDER_CONNECTOR_ERROR_ACCESS_DENIED; | $this->errorCode = CKFINDER_CONNECTOR_ERROR_ACCESS_DENIED; | ||||
$this->appendErrorNode($this->skippedFilesNode, $this->errorCode, $fileName, $fileType); | $this->appendErrorNode($this->skippedFilesNode, $this->errorCode, $fileName, $fileType); | ||||
} | } | ||||
else | else | ||||
{ | { | ||||
$this->extractTo($extractPath,$extractClientPath,$filePathInfo,$sFileName,$fileName); | $this->extractTo($extractPath,$extractClientPath,$filePathInfo,$sFileName,$fileName); | ||||
} | } | ||||
} | } | ||||
else | else | ||||
{ | { | ||||
// add to skipped files | // add to skipped files | ||||
$this->appendUnzippedNode($this->unzippedNodes,$fileName,'skip'); | $this->appendUnzippedNode($this->unzippedNodes,$fileName,'skip'); | ||||
} | } | ||||
} | } | ||||
else | else | ||||
{ | { | ||||
$this->errorCode = CKFINDER_CONNECTOR_ERROR_ALREADY_EXIST; | $this->errorCode = CKFINDER_CONNECTOR_ERROR_ALREADY_EXIST; | ||||
$this->appendErrorNode($this->skippedFilesNode, $this->errorCode, $fileName, $fileType); | $this->appendErrorNode($this->skippedFilesNode, $this->errorCode, $fileName, $fileType); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
// file doesn't exist yet | // file doesn't exist yet | ||||
else | else | ||||
{ | { | ||||
$this->extractTo($extractPath,$extractClientPath,$filePathInfo,$sFileName,$fileName); | $this->extractTo($extractPath,$extractClientPath,$filePathInfo,$sFileName,$fileName); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
$this->zip->close(); | $this->zip->close(); | ||||
$this->_connectorNode->addChild($this->unzippedNodes); | $this->_connectorNode->addChild($this->unzippedNodes); | ||||
if ($this->errorCode != CKFINDER_CONNECTOR_ERROR_NONE) { | if ($this->errorCode != CKFINDER_CONNECTOR_ERROR_NONE) { | ||||
$this->_connectorNode->addChild($this->skippedFilesNode); | $this->_connectorNode->addChild($this->skippedFilesNode); | ||||
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_ZIP_FAILED); | $this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_ZIP_FAILED); | ||||
} | } | ||||
} | } | ||||
public function onBeforeExecuteCommand( &$command ) | public function onBeforeExecuteCommand( &$command ) | ||||
{ | { | ||||
if ( $command == 'ExtractHere' ) | if ( $command == 'ExtractHere' ) | ||||
{ | { | ||||
$this->sendResponse(); | $this->sendResponse(); | ||||
return false; | return false; | ||||
} | } | ||||
return true ; | return true ; | ||||
} | } | ||||
} // end of CKFinder_Connector_CommandHandler_UnzipHere class | } // end of CKFinder_Connector_CommandHandler_UnzipHere class | ||||
class CKFinder_Connector_CommandHandler_UnzipTo extends CKFinder_Connector_CommandHandler_Unzip | class CKFinder_Connector_CommandHandler_UnzipTo extends CKFinder_Connector_CommandHandler_Unzip | ||||
{ | { | ||||
/** | /** | ||||
* Handle request and build XML | * Handle request and build XML | ||||
*/ | */ | ||||
protected function buildXml() | protected function buildXml() | ||||
{ | { | ||||
parent::buildXml(); | parent::buildXml(); | ||||
$extractDir = ( !empty($_POST['extractDir']) ) ? ltrim($_POST['extractDir'],'/') : ''; | $extractDir = ( !empty($_POST['extractDir']) ) ? ltrim($_POST['extractDir'],'/') : ''; | ||||
$extractDir = CKFinder_Connector_Utils_FileSystem::convertToFilesystemEncoding($extractDir); | $extractDir = CKFinder_Connector_Utils_FileSystem::convertToFilesystemEncoding($extractDir); | ||||
if ( preg_match(CKFINDER_REGEX_INVALID_PATH, $extractDir) ){ | if ( preg_match(CKFINDER_REGEX_INVALID_PATH, $extractDir) ){ | ||||
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_INVALID_REQUEST); | $this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_INVALID_REQUEST); | ||||
} | } | ||||
$extractPath = CKFinder_Connector_Utils_FileSystem::combinePaths($this->_currentFolder->getServerPath(), $extractDir.'/'); | $extractPath = CKFinder_Connector_Utils_FileSystem::combinePaths($this->_currentFolder->getServerPath(), $extractDir.'/'); | ||||
$extractClientPath = CKFinder_Connector_Utils_FileSystem::combinePaths($this->_currentFolder->getClientPath(),$extractDir); | $extractClientPath = CKFinder_Connector_Utils_FileSystem::combinePaths($this->_currentFolder->getClientPath(),$extractDir); | ||||
// acl for upload dir | // acl for upload dir | ||||
$_aclConfig = $this->_config->getAccessControlConfig(); | $_aclConfig = $this->_config->getAccessControlConfig(); | ||||
$aclMask = $_aclConfig->getComputedMask($this->_currentFolder->getResourceTypeName(),$extractDir); | $aclMask = $_aclConfig->getComputedMask($this->_currentFolder->getResourceTypeName(),$extractDir); | ||||
if ( !(($aclMask & CKFINDER_CONNECTOR_ACL_FOLDER_CREATE ) == CKFINDER_CONNECTOR_ACL_FOLDER_CREATE ) ){ | if ( !(($aclMask & CKFINDER_CONNECTOR_ACL_FOLDER_CREATE ) == CKFINDER_CONNECTOR_ACL_FOLDER_CREATE ) ){ | ||||
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_UNAUTHORIZED); | $this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_UNAUTHORIZED); | ||||
} | } | ||||
if ( empty( $_POST['force']) && file_exists($extractPath) && is_dir($extractPath) && !CKFinder_Connector_Utils_FileSystem::isEmptyDir($extractPath) ) | if ( empty( $_POST['force']) && file_exists($extractPath) && is_dir($extractPath) && !CKFinder_Connector_Utils_FileSystem::isEmptyDir($extractPath) ) | ||||
{ | { | ||||
$dirExists = new CKFinder_Connector_Utils_XmlNode("FolderExists"); | $dirExists = new CKFinder_Connector_Utils_XmlNode("FolderExists"); | ||||
$oErrorNode = new CKFinder_Connector_Utils_XmlNode("Folder"); | $oErrorNode = new CKFinder_Connector_Utils_XmlNode("Folder"); | ||||
$oErrorNode->addAttribute("name", $extractDir); | $oErrorNode->addAttribute("name", $extractDir); | ||||
$dirExists->addChild($oErrorNode); | $dirExists->addChild($oErrorNode); | ||||
$this->_connectorNode->addChild($dirExists); | $this->_connectorNode->addChild($dirExists); | ||||
return; | return; | ||||
} | } | ||||
elseif ( !empty( $_POST['force']) && $_POST['force'] =='overwrite' ) | elseif ( !empty( $_POST['force']) && $_POST['force'] =='overwrite' ) | ||||
{ | { | ||||
if ( !(($aclMask & CKFINDER_CONNECTOR_ACL_FILE_UPLOAD | CKFINDER_CONNECTOR_ACL_FILE_DELETE ) == CKFINDER_CONNECTOR_ACL_FILE_UPLOAD | CKFINDER_CONNECTOR_ACL_FILE_DELETE ) ){ | if ( !(($aclMask & CKFINDER_CONNECTOR_ACL_FILE_UPLOAD | CKFINDER_CONNECTOR_ACL_FILE_DELETE ) == CKFINDER_CONNECTOR_ACL_FILE_UPLOAD | CKFINDER_CONNECTOR_ACL_FILE_DELETE ) ){ | ||||
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_UNAUTHORIZED); | $this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_UNAUTHORIZED); | ||||
} | } | ||||
if ( $extractDir && file_exists($extractPath) && is_dir($extractPath) ) | if ( $extractDir && file_exists($extractPath) && is_dir($extractPath) ) | ||||
{ | { | ||||
if ( !(($aclMask & CKFINDER_CONNECTOR_ACL_FOLDER_CREATE | CKFINDER_CONNECTOR_ACL_FOLDER_DELETE ) == CKFINDER_CONNECTOR_ACL_FOLDER_CREATE | CKFINDER_CONNECTOR_ACL_FOLDER_DELETE ) ){ | if ( !(($aclMask & CKFINDER_CONNECTOR_ACL_FOLDER_CREATE | CKFINDER_CONNECTOR_ACL_FOLDER_DELETE ) == CKFINDER_CONNECTOR_ACL_FOLDER_CREATE | CKFINDER_CONNECTOR_ACL_FOLDER_DELETE ) ){ | ||||
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_UNAUTHORIZED); | $this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_UNAUTHORIZED); | ||||
} | } | ||||
if (!CKFinder_Connector_Utils_FileSystem::unlink($extractPath)) | if (!CKFinder_Connector_Utils_FileSystem::unlink($extractPath)) | ||||
{ | { | ||||
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_ACCESS_DENIED); | $this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_ACCESS_DENIED); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
else if ( !empty( $_POST['force']) && $_POST['force'] !== 'merge' ) | else if ( !empty( $_POST['force']) && $_POST['force'] !== 'merge' ) | ||||
{ | { | ||||
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_INVALID_REQUEST); | $this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_INVALID_REQUEST); | ||||
} | } | ||||
for ($i = 0; $i < $this->zip->numFiles; $i++) | for ($i = 0; $i < $this->zip->numFiles; $i++) | ||||
{ | { | ||||
$fileName = $this->zip->getNameIndex($i); | $fileName = $this->zip->getNameIndex($i); | ||||
$filePathInfo = pathinfo($fileName); | $filePathInfo = pathinfo($fileName); | ||||
$sFileName = $this->checkOneFile( $filePathInfo, $fileName ); | $sFileName = $this->checkOneFile( $filePathInfo, $fileName ); | ||||
// security test failed, add to skipped | // security test failed, add to skipped | ||||
if ( $sFileName ) | if ( $sFileName ) | ||||
{ | { | ||||
$this->extractTo($extractPath,$extractClientPath,$filePathInfo,$sFileName,$fileName); | $this->extractTo($extractPath,$extractClientPath,$filePathInfo,$sFileName,$fileName); | ||||
} | } | ||||
} | } | ||||
$this->zip->close(); | $this->zip->close(); | ||||
$this->_connectorNode->addChild($this->unzippedNodes); | $this->_connectorNode->addChild($this->unzippedNodes); | ||||
if ($this->errorCode != CKFINDER_CONNECTOR_ERROR_NONE) { | if ($this->errorCode != CKFINDER_CONNECTOR_ERROR_NONE) { | ||||
$this->_connectorNode->addChild($this->skippedFilesNode); | $this->_connectorNode->addChild($this->skippedFilesNode); | ||||
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_ZIP_FAILED); | $this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_ZIP_FAILED); | ||||
} | } | ||||
} | } | ||||
public function onBeforeExecuteCommand( &$command ) | public function onBeforeExecuteCommand( &$command ) | ||||
{ | { | ||||
if ( $command == 'ExtractTo'){ | if ( $command == 'ExtractTo'){ | ||||
$this->sendResponse(); | $this->sendResponse(); | ||||
return false; | return false; | ||||
} | } | ||||
return true ; | return true ; | ||||
} | } | ||||
} // end of CKFinder_Connector_CommandHandler_UnzipTo class | } // end of CKFinder_Connector_CommandHandler_UnzipTo class | ||||
class CKFinder_Connector_CommandHandler_CreateZip extends CKFinder_Connector_CommandHandler_XmlCommandHandlerBase | class CKFinder_Connector_CommandHandler_CreateZip extends CKFinder_Connector_CommandHandler_XmlCommandHandlerBase | ||||
{ | { | ||||
protected $_config; | protected $_config; | ||||
/** | /** | ||||
* Get private zip plugin config | * Get private zip plugin config | ||||
* | * | ||||
* @access protected | * @access protected | ||||
* @return array | * @return array | ||||
*/ | */ | ||||
protected function getConfig(){ | protected function getConfig(){ | ||||
$config = array(); | $config = array(); | ||||
$config['zipMaxSize'] = 'default'; | $config['zipMaxSize'] = 'default'; | ||||
if (isset($GLOBALS['config']['ZipMaxSize']) && (string)$GLOBALS['config']['ZipMaxSize']!='default' ){ | if (isset($GLOBALS['config']['ZipMaxSize']) && (string)$GLOBALS['config']['ZipMaxSize']!='default' ){ | ||||
$config['zipMaxSize'] = CKFinder_Connector_Utils_Misc::returnBytes((string)$GLOBALS['config']['ZipMaxSize']); | $config['zipMaxSize'] = CKFinder_Connector_Utils_Misc::returnBytes((string)$GLOBALS['config']['ZipMaxSize']); | ||||
} | } | ||||
return $config; | return $config; | ||||
} | } | ||||
/** | /** | ||||
* Checks given file for security | * Checks given file for security | ||||
* | * | ||||
* @param SplFileInfo $file | * @param SplFileInfo $file | ||||
* @access protected | * @access protected | ||||
* @return bool | * @return bool | ||||
*/ | */ | ||||
protected function checkOneFile($file) | protected function checkOneFile($file) | ||||
{ | { | ||||
$resourceTypeInfo = $this->_currentFolder->getResourceTypeConfig(); | $resourceTypeInfo = $this->_currentFolder->getResourceTypeConfig(); | ||||
$_aclConfig = $this->_config->getAccessControlConfig(); | $_aclConfig = $this->_config->getAccessControlConfig(); | ||||
$directory = str_replace('\\','/', $resourceTypeInfo->getDirectory()); | $directory = str_replace('\\','/', $resourceTypeInfo->getDirectory()); | ||||
$fileName = CKFinder_Connector_Utils_FileSystem::convertToFilesystemEncoding($file->getFilename()); | $fileName = CKFinder_Connector_Utils_FileSystem::convertToFilesystemEncoding($file->getFilename()); | ||||
if ($this->_config->forceAscii()) { | if ($this->_config->forceAscii()) { | ||||
$fileName = CKFinder_Connector_Utils_FileSystem::convertToAscii($fileName); | $fileName = CKFinder_Connector_Utils_FileSystem::convertToAscii($fileName); | ||||
} | } | ||||
$pathName = str_replace('\\','/', pathinfo($file->getPathname(), PATHINFO_DIRNAME) ); | $pathName = str_replace('\\','/', pathinfo($file->getPathname(), PATHINFO_DIRNAME) ); | ||||
$pathName = CKFinder_Connector_Utils_FileSystem::convertToFilesystemEncoding($pathName); | $pathName = CKFinder_Connector_Utils_FileSystem::convertToFilesystemEncoding($pathName); | ||||
// acl | // acl | ||||
$aclMask = $_aclConfig->getComputedMask($this->_currentFolder->getResourceTypeName(), str_ireplace($directory,'',$pathName)); | $aclMask = $_aclConfig->getComputedMask($this->_currentFolder->getResourceTypeName(), str_ireplace($directory,'',$pathName)); | ||||
$isAuthorized = (($aclMask & CKFINDER_CONNECTOR_ACL_FILE_VIEW) == CKFINDER_CONNECTOR_ACL_FILE_VIEW); | $isAuthorized = (($aclMask & CKFINDER_CONNECTOR_ACL_FILE_VIEW) == CKFINDER_CONNECTOR_ACL_FILE_VIEW); | ||||
if ( !$isAuthorized ){ | if ( !$isAuthorized ){ | ||||
return false; | return false; | ||||
} | } | ||||
// if it is a folder fileName represents the dir | // if it is a folder fileName represents the dir | ||||
if ( $file->isDir() && ( !CKFinder_Connector_Utils_FileSystem::checkFolderPath($fileName) || $resourceTypeInfo->checkIsHiddenPath($fileName) ) ){ | if ( $file->isDir() && ( !CKFinder_Connector_Utils_FileSystem::checkFolderPath($fileName) || $resourceTypeInfo->checkIsHiddenPath($fileName) ) ){ | ||||
return false; | return false; | ||||
} | } | ||||
// folder name | // folder name | ||||
if ( !CKFinder_Connector_Utils_FileSystem::checkFolderPath($pathName) ){ | if ( !CKFinder_Connector_Utils_FileSystem::checkFolderPath($pathName) ){ | ||||
return false; | return false; | ||||
} | } | ||||
// is hidden | // is hidden | ||||
if ( $resourceTypeInfo->checkIsHiddenPath($pathName) || $resourceTypeInfo->checkIsHiddenFile($fileName) ){ | if ( $resourceTypeInfo->checkIsHiddenPath($pathName) || $resourceTypeInfo->checkIsHiddenFile($fileName) ){ | ||||
return false; | return false; | ||||
} | } | ||||
// extension | // extension | ||||
if ( !$resourceTypeInfo->checkExtension($fileName) || !CKFinder_Connector_Utils_FileSystem::checkFileName($fileName) ){ | if ( !$resourceTypeInfo->checkExtension($fileName) || !CKFinder_Connector_Utils_FileSystem::checkFileName($fileName) ){ | ||||
return false; | return false; | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
/** | /** | ||||
* Get list of all files in given directory, including sub-directories | * Get list of all files in given directory, including sub-directories | ||||
* | * | ||||
* @param string $directory | * @param string $directory | ||||
* @param int $zipMaxSize Maximum zip file size | * @param int $zipMaxSize Maximum zip file size | ||||
* @return array $allFiles | * @return array $allFiles | ||||
*/ | */ | ||||
protected function getFilesRecursively( $directory, $zipMaxSize ) | protected function getFilesRecursively( $directory, $zipMaxSize ) | ||||
{ | { | ||||
$allFiles = array(); | $allFiles = array(); | ||||
$_zipFilesSize = 0; | $_zipFilesSize = 0; | ||||
$serverPath = str_replace('\\','/',$directory); | $serverPath = str_replace('\\','/',$directory); | ||||
foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory), RecursiveIteratorIterator::CHILD_FIRST) as $file ) { | foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory), RecursiveIteratorIterator::CHILD_FIRST) as $file ) { | ||||
if ( !$this->checkOneFile($file) ){ | if ( !$this->checkOneFile($file) ){ | ||||
continue; | continue; | ||||
} | } | ||||
if ( !empty($zipMaxSize) ){ | if ( !empty($zipMaxSize) ){ | ||||
clearstatcache(); | clearstatcache(); | ||||
$_zipFilesSize += $file->getSize(); | $_zipFilesSize += $file->getSize(); | ||||
if ( $_zipFilesSize > $zipMaxSize ) { | if ( $_zipFilesSize > $zipMaxSize ) { | ||||
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_CREATED_FILE_TOO_BIG); | $this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_CREATED_FILE_TOO_BIG); | ||||
} | } | ||||
} | } | ||||
$pathName = str_replace('\\','/',$file->getPathname()); | $pathName = str_replace('\\','/',$file->getPathname()); | ||||
if ( $file->isDir() ){ | if ( $file->isDir() ){ | ||||
// skip dot folders on unix systems ( do not try to use isDot() as $file is not a DirectoryIterator obj ) | // skip dot folders on unix systems ( do not try to use isDot() as $file is not a DirectoryIterator obj ) | ||||
if ( in_array($file->getFilename(),array('..','.')) ){ | if ( in_array($file->getFilename(),array('..','.')) ){ | ||||
continue; | continue; | ||||
} | } | ||||
if ($pathName != rtrim($serverPath,'/')){ | if ($pathName != rtrim($serverPath,'/')){ | ||||
$allFiles[ ltrim(str_ireplace(rtrim($serverPath,'/'),'',$pathName),'/') ] = ''; | $allFiles[ ltrim(str_ireplace(rtrim($serverPath,'/'),'',$pathName),'/') ] = ''; | ||||
} | } | ||||
} else { | } else { | ||||
$allFiles[$pathName] = str_ireplace($serverPath,'',$pathName); | $allFiles[$pathName] = str_ireplace($serverPath,'',$pathName); | ||||
} | } | ||||
} | } | ||||
return $allFiles; | return $allFiles; | ||||
} | } | ||||
/** | /** | ||||
* Handle request and build XML | * Handle request and build XML | ||||
*/ | */ | ||||
public function buildXml() | public function buildXml() | ||||
{ | { | ||||
if (!extension_loaded('zip')) { | if (!extension_loaded('zip')) { | ||||
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_INVALID_COMMAND); | $this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_INVALID_COMMAND); | ||||
} | } | ||||
$this->checkConnector(); | $this->checkConnector(); | ||||
$this->checkRequest(); | $this->checkRequest(); | ||||
if ( !$this->_currentFolder->checkAcl(CKFINDER_CONNECTOR_ACL_FILE_UPLOAD)) { | if ( !$this->_currentFolder->checkAcl(CKFINDER_CONNECTOR_ACL_FILE_UPLOAD)) { | ||||
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_UNAUTHORIZED); | $this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_UNAUTHORIZED); | ||||
} | } | ||||
$this->_config =& CKFinder_Connector_Core_Factory::getInstance("Core_Config"); | $this->_config =& CKFinder_Connector_Core_Factory::getInstance("Core_Config"); | ||||
$currentResourceTypeConfig = $this->_currentFolder->getResourceTypeConfig(); | $currentResourceTypeConfig = $this->_currentFolder->getResourceTypeConfig(); | ||||
$_sServerDir = $this->_currentFolder->getServerPath(); | $_sServerDir = $this->_currentFolder->getServerPath(); | ||||
$files = array(); | $files = array(); | ||||
$_zipFilesSize = 0; | $_zipFilesSize = 0; | ||||
$config = $this->getConfig(); | $config = $this->getConfig(); | ||||
$zipMaxSize = $config['zipMaxSize']; | $zipMaxSize = $config['zipMaxSize']; | ||||
if ( !empty($zipMaxSize) && $zipMaxSize == 'default' ){ | if ( !empty($zipMaxSize) && $zipMaxSize == 'default' ){ | ||||
$zipMaxSize = $currentResourceTypeConfig->getMaxSize(); | $zipMaxSize = $currentResourceTypeConfig->getMaxSize(); | ||||
} | } | ||||
$_isBasket = ( isset($_POST['basket']) && $_POST['basket'] == 'true' )? true : false; | $_isBasket = ( isset($_POST['basket']) && $_POST['basket'] == 'true' )? true : false; | ||||
if ( !empty($_POST['files'])) | if ( !empty($_POST['files'])) | ||||
{ | { | ||||
$_aclConfig = $this->_config->getAccessControlConfig(); | $_aclConfig = $this->_config->getAccessControlConfig(); | ||||
$aclMasks = array(); | $aclMasks = array(); | ||||
$_resourceTypeConfig = array(); | $_resourceTypeConfig = array(); | ||||
foreach ( $_POST['files'] as $arr ){ | foreach ( $_POST['files'] as $arr ){ | ||||
if ( empty($arr['name']) || empty($arr['type']) || empty($arr['folder']) ) { | if ( empty($arr['name']) || empty($arr['type']) || empty($arr['folder']) ) { | ||||
continue; | continue; | ||||
} | } | ||||
// file name | // file name | ||||
$name = CKFinder_Connector_Utils_FileSystem::convertToFilesystemEncoding($arr['name']); | $name = CKFinder_Connector_Utils_FileSystem::convertToFilesystemEncoding($arr['name']); | ||||
// resource type | // resource type | ||||
$type = $arr['type']; | $type = $arr['type']; | ||||
// client path | // client path | ||||
$path = CKFinder_Connector_Utils_FileSystem::convertToFilesystemEncoding($arr['folder']); | $path = CKFinder_Connector_Utils_FileSystem::convertToFilesystemEncoding($arr['folder']); | ||||
// check #1 (path) | // check #1 (path) | ||||
if (!CKFinder_Connector_Utils_FileSystem::checkFileName($name) || preg_match(CKFINDER_REGEX_INVALID_PATH, $path)) { | if (!CKFinder_Connector_Utils_FileSystem::checkFileName($name) || preg_match(CKFINDER_REGEX_INVALID_PATH, $path)) { | ||||
continue; | continue; | ||||
} | } | ||||
// get resource type config for current file | // get resource type config for current file | ||||
if (!isset($_resourceTypeConfig[$type])) { | if (!isset($_resourceTypeConfig[$type])) { | ||||
$_resourceTypeConfig[$type] = $this->_config->getResourceTypeConfig($type); | $_resourceTypeConfig[$type] = $this->_config->getResourceTypeConfig($type); | ||||
} | } | ||||
// check #2 (resource type) | // check #2 (resource type) | ||||
if (is_null($_resourceTypeConfig[$type])) { | if (is_null($_resourceTypeConfig[$type])) { | ||||
continue; | continue; | ||||
} | } | ||||
// check #3 (extension) | // check #3 (extension) | ||||
if (!$_resourceTypeConfig[$type]->checkExtension($name, false)) { | if (!$_resourceTypeConfig[$type]->checkExtension($name, false)) { | ||||
continue; | continue; | ||||
} | } | ||||
// check #4 (extension) - when moving to another resource type, double check extension | // check #4 (extension) - when moving to another resource type, double check extension | ||||
if ($currentResourceTypeConfig->getName() != $type && !$currentResourceTypeConfig->checkExtension($name, false)) { | if ($currentResourceTypeConfig->getName() != $type && !$currentResourceTypeConfig->checkExtension($name, false)) { | ||||
continue; | continue; | ||||
} | } | ||||
// check #5 (hidden folders) | // check #5 (hidden folders) | ||||
// cache results | // cache results | ||||
if (empty($checkedPaths[$path])) { | if (empty($checkedPaths[$path])) { | ||||
$checkedPaths[$path] = true; | $checkedPaths[$path] = true; | ||||
if ($_resourceTypeConfig[$type]->checkIsHiddenPath($path)) { | if ($_resourceTypeConfig[$type]->checkIsHiddenPath($path)) { | ||||
continue; | continue; | ||||
} | } | ||||
} | } | ||||
// check #6 (hidden file name) | // check #6 (hidden file name) | ||||
if ($currentResourceTypeConfig->checkIsHiddenFile($name)) { | if ($currentResourceTypeConfig->checkIsHiddenFile($name)) { | ||||
continue; | continue; | ||||
} | } | ||||
// check #7 (Access Control, need file view permission to source files) | // check #7 (Access Control, need file view permission to source files) | ||||
if (!isset($aclMasks[$type."@".$path])) { | if (!isset($aclMasks[$type."@".$path])) { | ||||
$aclMasks[$type."@".$path] = $_aclConfig->getComputedMask($type, $path); | $aclMasks[$type."@".$path] = $_aclConfig->getComputedMask($type, $path); | ||||
} | } | ||||
$isAuthorized = (($aclMasks[$type."@".$path] & CKFINDER_CONNECTOR_ACL_FILE_VIEW) == CKFINDER_CONNECTOR_ACL_FILE_VIEW); | $isAuthorized = (($aclMasks[$type."@".$path] & CKFINDER_CONNECTOR_ACL_FILE_VIEW) == CKFINDER_CONNECTOR_ACL_FILE_VIEW); | ||||
if (!$isAuthorized) { | if (!$isAuthorized) { | ||||
continue; | continue; | ||||
} | } | ||||
$sourceFilePath = CKFinder_Connector_Utils_FileSystem::combinePaths($_resourceTypeConfig[$type]->getDirectory().$path,$name); | $sourceFilePath = CKFinder_Connector_Utils_FileSystem::combinePaths($_resourceTypeConfig[$type]->getDirectory().$path,$name); | ||||
// check #8 (invalid file name) | // check #8 (invalid file name) | ||||
if (!file_exists($sourceFilePath) || !is_file($sourceFilePath)) { | if (!file_exists($sourceFilePath) || !is_file($sourceFilePath)) { | ||||
continue; | continue; | ||||
} | } | ||||
// check #9 - max file size | // check #9 - max file size | ||||
if ( !empty($zipMaxSize) ){ | if ( !empty($zipMaxSize) ){ | ||||
clearstatcache(); | clearstatcache(); | ||||
$_zipFilesSize += filesize($sourceFilePath); | $_zipFilesSize += filesize($sourceFilePath); | ||||
if ( $_zipFilesSize > $zipMaxSize ) { | if ( $_zipFilesSize > $zipMaxSize ) { | ||||
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_CREATED_FILE_TOO_BIG); | $this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_CREATED_FILE_TOO_BIG); | ||||
} | } | ||||
} | } | ||||
$zipPathPart = ( $_isBasket ) ? CKFinder_Connector_Utils_FileSystem::combinePaths($type,$path) : ''; | $zipPathPart = ( $_isBasket ) ? CKFinder_Connector_Utils_FileSystem::combinePaths($type,$path) : ''; | ||||
$files[$sourceFilePath] = $zipPathPart.pathinfo($sourceFilePath,PATHINFO_BASENAME); | $files[$sourceFilePath] = $zipPathPart.pathinfo($sourceFilePath,PATHINFO_BASENAME); | ||||
} | } | ||||
} | } | ||||
else | else | ||||
{ | { | ||||
if (!is_dir($_sServerDir)) { | if (!is_dir($_sServerDir)) { | ||||
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_FOLDER_NOT_FOUND); | $this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_FOLDER_NOT_FOUND); | ||||
} | } | ||||
$files = $this->getFilesRecursively($_sServerDir,$zipMaxSize); | $files = $this->getFilesRecursively($_sServerDir,$zipMaxSize); | ||||
} | } | ||||
if ( sizeof($files)<1) { | if ( sizeof($files)<1) { | ||||
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_FILE_NOT_FOUND); | $this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_FILE_NOT_FOUND); | ||||
} | } | ||||
// default destination dir - temp | // default destination dir - temp | ||||
$dest_dir = CKFinder_Connector_Utils_FileSystem::getTmpDir(); | $dest_dir = CKFinder_Connector_Utils_FileSystem::getTmpDir(); | ||||
$resourceTypeInfo = $this->_currentFolder->getResourceTypeConfig(); | $resourceTypeInfo = $this->_currentFolder->getResourceTypeConfig(); | ||||
// default file name - hash | // default file name - hash | ||||
$zip_filename = substr(md5(serialize($files)), 0, 16).$resourceTypeInfo->getHash().'.zip'; | $zip_filename = substr(md5(serialize($files)), 0, 16).$resourceTypeInfo->getHash().'.zip'; | ||||
// compress files - do not download them | // compress files - do not download them | ||||
// change destination and name | // change destination and name | ||||
if ( isset($_POST['download']) && $_POST['download'] == 'false'){ | if ( isset($_POST['download']) && $_POST['download'] == 'false'){ | ||||
$dest_dir = $_sServerDir; | $dest_dir = $_sServerDir; | ||||
if ( isset($_POST['zipName']) && !empty($_POST['zipName'])){ | if ( isset($_POST['zipName']) && !empty($_POST['zipName'])){ | ||||
$zip_filename = CKFinder_Connector_Utils_FileSystem::convertToFilesystemEncoding($_POST['zipName']); | $zip_filename = CKFinder_Connector_Utils_FileSystem::convertToFilesystemEncoding($_POST['zipName']); | ||||
if (!$resourceTypeInfo->checkExtension($zip_filename)) { | if (!$resourceTypeInfo->checkExtension($zip_filename)) { | ||||
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_INVALID_EXTENSION); | $this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_INVALID_EXTENSION); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
if (!CKFinder_Connector_Utils_FileSystem::checkFileName($zip_filename) || $resourceTypeInfo->checkIsHiddenFile($zip_filename)) { | if (!CKFinder_Connector_Utils_FileSystem::checkFileName($zip_filename) || $resourceTypeInfo->checkIsHiddenFile($zip_filename)) { | ||||
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_INVALID_NAME); | $this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_INVALID_NAME); | ||||
} | } | ||||
if ($this->_config->forceAscii()) { | if ($this->_config->forceAscii()) { | ||||
$zip_filename = CKFinder_Connector_Utils_FileSystem::convertToAscii($zip_filename); | $zip_filename = CKFinder_Connector_Utils_FileSystem::convertToAscii($zip_filename); | ||||
} | } | ||||
$zipFilePath = CKFinder_Connector_Utils_FileSystem::combinePaths($dest_dir, $zip_filename); | $zipFilePath = CKFinder_Connector_Utils_FileSystem::combinePaths($dest_dir, $zip_filename); | ||||
if (!is_writable(dirname($zipFilePath))) { | if (!is_writable(dirname($zipFilePath))) { | ||||
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_ACCESS_DENIED); | $this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_ACCESS_DENIED); | ||||
} | } | ||||
// usually we would need to create zip? | // usually we would need to create zip? | ||||
$createZip = true; | $createZip = true; | ||||
// only if file already exists and we want download it | // only if file already exists and we want download it | ||||
// do not create new one - because hash of previously created is the same - existing archive is ok | // do not create new one - because hash of previously created is the same - existing archive is ok | ||||
if ( file_exists($zipFilePath) && isset($_POST['download']) && $_POST['download'] == 'true' ){ | if ( file_exists($zipFilePath) && isset($_POST['download']) && $_POST['download'] == 'true' ){ | ||||
$createZip = false; | $createZip = false; | ||||
} | } | ||||
// if we only want to create archive | // if we only want to create archive | ||||
else | else | ||||
{ | { | ||||
if ( file_exists($zipFilePath) && ( !isset($_POST['fileExistsAction']) || !in_array($_POST['fileExistsAction'], array('autorename','overwrite')) ) ){ | if ( file_exists($zipFilePath) && ( !isset($_POST['fileExistsAction']) || !in_array($_POST['fileExistsAction'], array('autorename','overwrite')) ) ){ | ||||
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_ALREADY_EXIST); | $this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_ALREADY_EXIST); | ||||
} | } | ||||
if ( !$this->_currentFolder->checkAcl( CKFINDER_CONNECTOR_ACL_FILE_UPLOAD )) { | if ( !$this->_currentFolder->checkAcl( CKFINDER_CONNECTOR_ACL_FILE_UPLOAD )) { | ||||
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_UNAUTHORIZED); | $this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_UNAUTHORIZED); | ||||
} | } | ||||
// check how to deal with existing file | // check how to deal with existing file | ||||
if ( isset($_POST['fileExistsAction']) && $_POST['fileExistsAction'] == 'autorename' ) | if ( isset($_POST['fileExistsAction']) && $_POST['fileExistsAction'] == 'autorename' ) | ||||
{ | { | ||||
if ( !$this->_currentFolder->checkAcl(CKFINDER_CONNECTOR_ACL_FILE_UPLOAD | CKFINDER_CONNECTOR_ACL_FILE_RENAME )) { | if ( !$this->_currentFolder->checkAcl(CKFINDER_CONNECTOR_ACL_FILE_UPLOAD | CKFINDER_CONNECTOR_ACL_FILE_RENAME )) { | ||||
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_UNAUTHORIZED); | $this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_UNAUTHORIZED); | ||||
} | } | ||||
$zip_filename = CKFinder_Connector_Utils_FileSystem::autoRename($dest_dir, $zip_filename); | $zip_filename = CKFinder_Connector_Utils_FileSystem::autoRename($dest_dir, $zip_filename); | ||||
$zipFilePath = CKFinder_Connector_Utils_FileSystem::combinePaths($dest_dir, $zip_filename); | $zipFilePath = CKFinder_Connector_Utils_FileSystem::combinePaths($dest_dir, $zip_filename); | ||||
} | } | ||||
elseif ( isset($_POST['fileExistsAction']) && $_POST['fileExistsAction'] == 'overwrite' ) | elseif ( isset($_POST['fileExistsAction']) && $_POST['fileExistsAction'] == 'overwrite' ) | ||||
{ | { | ||||
if ( !$this->_currentFolder->checkAcl(CKFINDER_CONNECTOR_ACL_FILE_RENAME | CKFINDER_CONNECTOR_ACL_FILE_DELETE)) { | if ( !$this->_currentFolder->checkAcl(CKFINDER_CONNECTOR_ACL_FILE_RENAME | CKFINDER_CONNECTOR_ACL_FILE_DELETE)) { | ||||
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_UNAUTHORIZED); | $this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_UNAUTHORIZED); | ||||
} | } | ||||
if (!CKFinder_Connector_Utils_FileSystem::unlink($zipFilePath)){ | if (!CKFinder_Connector_Utils_FileSystem::unlink($zipFilePath)){ | ||||
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_ACCESS_DENIED); | $this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_ACCESS_DENIED); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
if ( $createZip ){ | if ( $createZip ){ | ||||
$zip = new ZipArchive(); | $zip = new ZipArchive(); | ||||
$result = $zip->open( $zipFilePath, ZIPARCHIVE::CREATE); | $result = $zip->open( $zipFilePath, ZIPARCHIVE::CREATE); | ||||
if ( $result !== TRUE ) { | if ( $result !== TRUE ) { | ||||
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_UNKNOWN); | $this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_UNKNOWN); | ||||
} | } | ||||
foreach ( $files as $pathname => $filename ){ | foreach ( $files as $pathname => $filename ){ | ||||
if ( !empty($filename) ){ | if ( !empty($filename) ){ | ||||
if ( file_exists($pathname) && is_readable($pathname) ){ | if ( file_exists($pathname) && is_readable($pathname) ){ | ||||
$zip->addFile( $pathname, $filename ); | $zip->addFile( $pathname, $filename ); | ||||
} | } | ||||
} else { | } else { | ||||
$zip->addEmptyDir( $pathname ); | $zip->addEmptyDir( $pathname ); | ||||
} | } | ||||
} | } | ||||
$zip->close(); | $zip->close(); | ||||
} | } | ||||
$file = new CKFinder_Connector_Utils_XmlNode("ZipFile"); | $file = new CKFinder_Connector_Utils_XmlNode("ZipFile"); | ||||
$file->addAttribute("name", $zip_filename); | $file->addAttribute("name", $zip_filename); | ||||
$this->_connectorNode->addChild($file); | $this->_connectorNode->addChild($file); | ||||
} | } | ||||
public function onBeforeExecuteCommand( &$command ) | public function onBeforeExecuteCommand( &$command ) | ||||
{ | { | ||||
if ( $command == 'CreateZip'){ | if ( $command == 'CreateZip'){ | ||||
$this->sendResponse(); | $this->sendResponse(); | ||||
return false; | return false; | ||||
} | } | ||||
return true ; | return true ; | ||||
} | } | ||||
} // end of CKFinder_Connector_CommandHandler_DownloadZip class | } // end of CKFinder_Connector_CommandHandler_DownloadZip class | ||||
class CKFinder_Connector_CommandHandler_DownloadZip extends CKFinder_Connector_CommandHandler_CreateZip | class CKFinder_Connector_CommandHandler_DownloadZip extends CKFinder_Connector_CommandHandler_CreateZip | ||||
{ | { | ||||
/** | /** | ||||
* Sends generated zip file to the user | * Sends generated zip file to the user | ||||
*/ | */ | ||||
protected function sendZipFile() | protected function sendZipFile() | ||||
{ | { | ||||
if (!function_exists('ob_list_handlers') || ob_list_handlers()) { | if (!function_exists('ob_list_handlers') || ob_list_handlers()) { | ||||
@ob_end_clean(); | @ob_end_clean(); | ||||
} | } | ||||
header("Content-Encoding: none"); | header("Content-Encoding: none"); | ||||
$this->checkConnector(); | $this->checkConnector(); | ||||
$this->checkRequest(); | $this->checkRequest(); | ||||
// empty wystarczy | // empty wystarczy | ||||
if ( empty($_GET['FileName']) ){ | if ( empty($_GET['FileName']) ){ | ||||
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_FILE_NOT_FOUND); | $this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_FILE_NOT_FOUND); | ||||
} | } | ||||
$resourceTypeInfo = $this->_currentFolder->getResourceTypeConfig(); | $resourceTypeInfo = $this->_currentFolder->getResourceTypeConfig(); | ||||
$hash = $resourceTypeInfo->getHash(); | $hash = $resourceTypeInfo->getHash(); | ||||
if ( $hash !== $_GET['hash'] || $hash !== substr($_GET['FileName'],16,16) ){ | if ( $hash !== $_GET['hash'] || $hash !== substr($_GET['FileName'],16,16) ){ | ||||
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_INVALID_REQUEST); | $this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_INVALID_REQUEST); | ||||
} | } | ||||
if (!$this->_currentFolder->checkAcl(CKFINDER_CONNECTOR_ACL_FILE_VIEW)) { | if (!$this->_currentFolder->checkAcl(CKFINDER_CONNECTOR_ACL_FILE_VIEW)) { | ||||
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_UNAUTHORIZED); | $this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_UNAUTHORIZED); | ||||
} | } | ||||
$fileName = CKFinder_Connector_Utils_FileSystem::convertToFilesystemEncoding(trim($_GET['FileName'])); | $fileName = CKFinder_Connector_Utils_FileSystem::convertToFilesystemEncoding(trim($_GET['FileName'])); | ||||
if (!CKFinder_Connector_Utils_FileSystem::checkFileName($fileName)) { | if (!CKFinder_Connector_Utils_FileSystem::checkFileName($fileName)) { | ||||
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_INVALID_REQUEST); | $this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_INVALID_REQUEST); | ||||
} | } | ||||
if ( strtolower(pathinfo($fileName, PATHINFO_EXTENSION)) !== 'zip'){ | if ( strtolower(pathinfo($fileName, PATHINFO_EXTENSION)) !== 'zip'){ | ||||
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_INVALID_EXTENSION); | $this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_INVALID_EXTENSION); | ||||
} | } | ||||
$dest_dir = CKFinder_Connector_Utils_FileSystem::getTmpDir(); | $dest_dir = CKFinder_Connector_Utils_FileSystem::getTmpDir(); | ||||
$filePath = CKFinder_Connector_Utils_FileSystem::combinePaths($dest_dir,$fileName); | $filePath = CKFinder_Connector_Utils_FileSystem::combinePaths($dest_dir,$fileName); | ||||
if ( !file_exists($filePath) || !is_file($filePath)) { | if ( !file_exists($filePath) || !is_file($filePath)) { | ||||
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_FILE_NOT_FOUND); | $this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_FILE_NOT_FOUND); | ||||
} | } | ||||
if (!is_readable($filePath)) { | if (!is_readable($filePath)) { | ||||
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_ACCESS_DENIED); | $this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_ACCESS_DENIED); | ||||
} | } | ||||
$zipFileName = CKFinder_Connector_Utils_FileSystem::convertToFilesystemEncoding(trim($_GET['ZipName'])); | $zipFileName = CKFinder_Connector_Utils_FileSystem::convertToFilesystemEncoding(trim($_GET['ZipName'])); | ||||
if (!CKFinder_Connector_Utils_FileSystem::checkFileName($zipFileName)) { | if (!CKFinder_Connector_Utils_FileSystem::checkFileName($zipFileName)) { | ||||
$this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_INVALID_REQUEST); | $this->_errorHandler->throwError(CKFINDER_CONNECTOR_ERROR_INVALID_REQUEST); | ||||
} | } | ||||
$fileFilename = pathinfo($zipFileName,PATHINFO_BASENAME ); | $fileFilename = pathinfo($zipFileName,PATHINFO_BASENAME ); | ||||
header("Content-Encoding: none"); | header("Content-Encoding: none"); | ||||
header("Cache-Control: cache, must-revalidate"); | header("Cache-Control: cache, must-revalidate"); | ||||
header("Pragma: public"); | header("Pragma: public"); | ||||
header("Expires: 0"); | header("Expires: 0"); | ||||
$user_agent = !empty($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : ""; | $user_agent = !empty($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : ""; | ||||
$encodedName = str_replace("\"", "\\\"", $fileFilename); | $encodedName = str_replace("\"", "\\\"", $fileFilename); | ||||
if (strpos($user_agent, "MSIE") !== false) { | if (strpos($user_agent, "MSIE") !== false) { | ||||
$encodedName = str_replace(array("+", "%2E"), array(" ", "."), urlencode($encodedName)); | $encodedName = str_replace(array("+", "%2E"), array(" ", "."), urlencode($encodedName)); | ||||
} | } | ||||
header("Content-type: application/octet-stream; name=\"" . $fileFilename . "\""); | header("Content-type: application/octet-stream; name=\"" . $fileFilename . "\""); | ||||
header("Content-Disposition: attachment; filename=\"" . $encodedName. "\""); | header("Content-Disposition: attachment; filename=\"" . $encodedName. "\""); | ||||
header("Content-Length: " . filesize($filePath)); | header("Content-Length: " . filesize($filePath)); | ||||
CKFinder_Connector_Utils_FileSystem::sendFile($filePath); | CKFinder_Connector_Utils_FileSystem::sendFile($filePath); | ||||
exit; | exit; | ||||
} | } | ||||
public function onBeforeExecuteCommand( &$command ) | public function onBeforeExecuteCommand( &$command ) | ||||
{ | { | ||||
if ( $command == 'DownloadZip'){ | if ( $command == 'DownloadZip'){ | ||||
$this->sendZipFile(); | $this->sendZipFile(); | ||||
return false; | return false; | ||||
} | } | ||||
return true ; | return true ; | ||||
} | } | ||||
} // end of CKFinder_Connector_CommandHandler_DownloadZip | } // end of CKFinder_Connector_CommandHandler_DownloadZip | ||||
if (extension_loaded('zip')) | if (extension_loaded('zip')) | ||||
{ | { | ||||
$CommandHandler_UnzipHere = new CKFinder_Connector_CommandHandler_UnzipHere(); | $CommandHandler_UnzipHere = new CKFinder_Connector_CommandHandler_UnzipHere(); | ||||
$CommandHandler_UnzipTo = new CKFinder_Connector_CommandHandler_UnzipTo(); | $CommandHandler_UnzipTo = new CKFinder_Connector_CommandHandler_UnzipTo(); | ||||
$CommandHandler_CreateZip = new CKFinder_Connector_CommandHandler_CreateZip(); | $CommandHandler_CreateZip = new CKFinder_Connector_CommandHandler_CreateZip(); | ||||
$CommandHandler_DownloadZip = new CKFinder_Connector_CommandHandler_DownloadZip(); | $CommandHandler_DownloadZip = new CKFinder_Connector_CommandHandler_DownloadZip(); | ||||
$config['Hooks']['BeforeExecuteCommand'][] = array($CommandHandler_UnzipHere, "onBeforeExecuteCommand"); | $config['Hooks']['BeforeExecuteCommand'][] = array($CommandHandler_UnzipHere, "onBeforeExecuteCommand"); | ||||
$config['Hooks']['BeforeExecuteCommand'][] = array($CommandHandler_UnzipTo, "onBeforeExecuteCommand"); | $config['Hooks']['BeforeExecuteCommand'][] = array($CommandHandler_UnzipTo, "onBeforeExecuteCommand"); | ||||
$config['Hooks']['BeforeExecuteCommand'][] = array($CommandHandler_CreateZip, "onBeforeExecuteCommand"); | $config['Hooks']['BeforeExecuteCommand'][] = array($CommandHandler_CreateZip, "onBeforeExecuteCommand"); | ||||
$config['Hooks']['BeforeExecuteCommand'][] = array($CommandHandler_DownloadZip, "onBeforeExecuteCommand"); | $config['Hooks']['BeforeExecuteCommand'][] = array($CommandHandler_DownloadZip, "onBeforeExecuteCommand"); | ||||
$config['Plugins'][] = 'zip'; | $config['Plugins'][] = 'zip'; | ||||
} | } |