<?php
/**
* @version	$Id: fck_helper.php 15325 2012-04-26 15:32:41Z alex $
* @package	In-Portal
* @copyright	Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license      GNU/GPL
* In-Portal is Open Source software.
* This means that this software may have been modified pursuant
* the GNU General Public License, and as distributed it includes
* or is derivative of works licensed under the GNU General Public License
* or other free or open source software licenses.
* See http://www.in-portal.org/license for copyright notices and details.
*/

defined('FULL_PATH') or die('restricted access!');

class fckFCKHelper extends kHelper {

	var $Config = Array();

	/**
	 * Currently selected folder
	 *
	 * @var string
	 * @access protected
	 */
	protected $folder = '';

	/**
	 * Current sorting field
	 *
	 * @var string
	 * @access protected
	 */
	protected $sortField = '';

	/**
	 * Current sorting direction
	 *
	 * @var string
	 * @access protected
	 */
	protected $sortDirection = '';

	public function __construct()
	{
		parent::__construct();

		$this->folder = $this->Application->GetVar('folder');
		$this->sortField = $this->Application->GetVar('sort_by');
		$this->sortDirection = $this->Application->GetVar('order_by');

		$this->Config['AllowedExtensions']['Files']	= Array('jpg','gif','jpeg','png','swf','fla','jpg','gif','jpeg','png','avi','mpg','mpeg','zip','rar','arj','gz','tar','doc','pdf','ppt','rdp','swf','swt','txt','vsd','xls','csv','odt');
		$this->Config['DeniedExtensions']['Files']	= Array('php','asp','aspx','ascx','jsp','cfm','cfc','pl','bat','exe','dll','reg');
		$this->Config['AllowedExtensions']['Images'] = Array('jpg','gif','jpeg','png', 'bmp');
		$this->Config['DeniedExtensions']['Images']	= Array('php','asp','aspx','ascx','jsp','cfm','cfc','pl','bat','exe','dll','reg');
		$this->Config['AllowedExtensions']['Flash']	= Array('swf','fla');
		$this->Config['DeniedExtensions']['Flash']	= Array('php','asp','aspx','ascx','jsp','cfm','cfc','pl','bat','exe','dll','reg');
		$this->Config['AllowedExtensions']['Media']	= Array('asf','asx','avi','wav','wax','wma','wm','wmv','m3u','mp2v','mpg','mpeg','m1v','mp2','mp3','mpa','mpe','mpv2','mp4','mid','midi','rmi','qt','aif','aifc','aiff','mov','flv','rm','svcd','swf','vcd');
		$this->Config['DeniedExtensions']['Media']	= Array('php','asp','aspx','ascx','jsp','cfm','cfc','pl','bat','exe','dll','reg');
		$this->Config['AllowedExtensions']['Documents']	= Array('doc','pdf','ppt','rdp','swf','swt','txt','vsd','xls','csv','zip','odt');
		$this->Config['DeniedExtensions']['Documents']	= Array('php','asp','aspx','ascx','jsp','cfm','cfc','pl','bat','exe','dll','reg');

		$this->Config['ExtensionIcons'] = Array('ai','avi','bmp','cs','dll','doc','exe','fla','gif','htm','html','jpg','js','mdb','mp3','pdf','png','ppt','rdp','swf','swt','txt','vsd','xls','xml','zip');
	}

	function CreateFolder($folder = '')
	{
		if ( !$folder ) {
			return false;
		}

		$folderPath = WRITEABLE . '/user_files/' . $folder;

		if ( file_exists($folderPath) && is_dir($folderPath) ) {
			return true;
		}

		/*$permissions = defined('FCK_FOLDERS_PERMISSIONS') ? FCK_FOLDERS_PERMISSIONS : '0777';
		return mkdir($folderPath, $permissions);*/

		return mkdir($folderPath);
	}

	function IsAllowedExtension($folder, $file_name)
	{
		$ext = strtolower( pathinfo($file_name, PATHINFO_EXTENSION) );

		if ( isset($this->Config['DeniedExtensions'][$folder]) ) {
			if ( in_array($ext, $this->Config['DeniedExtensions'][$folder]) ) {
				return false;
			}
		}

		if ( isset($this->Config['AllowedExtensions'][$folder]) ) {
			if ( !in_array($ext, $this->Config['AllowedExtensions'][$folder]) ) {
				return false;
			}
		}

		return true;
	}

	/**
	 * Returns list of sub-folders from given folder (automatically excludes system folders)
	 *
	 * @param string $files_dir
	 * @return Array
	 * @access public
	 */
	public function ReadFolders($files_dir)
	{
		$ret = Array ();
		$system_folders = defined('KERNEL_SYSTEM_FOLDERS') ? KERNEL_SYSTEM_FOLDERS : Array ('icons', 'CVS', '.svn');

		try {
			$iterator = new DirectoryIterator($files_dir);
			/* @var $file_info DirectoryIterator */
		}
		catch (UnexpectedValueException $e) {
			return $ret;
		}

		foreach ($iterator as $file_info) {
			$filename = $file_info->getFilename();

			if ( $file_info->isDir() && !$file_info->isDot() ) {
				$ret[] = $filename;
			}
		}

		return array_diff($ret, $system_folders);
	}

	/**
	 * Returns list of files in given folder
	 *
	 * @param string $files_dir
	 * @return Array
	 * @access public
	 */
	public function ReadFiles($files_dir)
	{
		$ret = Array ();

		try {
			$iterator = new DirectoryIterator($files_dir);
			/* @var $file_info DirectoryIterator */
		}
		catch (UnexpectedValueException $e) {
			return $ret;
		}

		foreach ($iterator as $file_info) {
			if ( !$file_info->isDir() ) {
				$ret[] = $file_info->getFilename();
			}
		}

		return $ret;
	}

	/**
	 * Returns xml containing list of folders in current folder
	 *
	 * @return string
	 * @access public
	 */
	public function PrintFolders()
	{
		$files_dir = WRITEABLE . '/user_files/' . $this->folder . '/';

		$sub_folders = $this->ReadFolders($files_dir);
		natcasesort($sub_folders);

		$ret = $this->_buildFoldersXML($sub_folders, 'folder2');

		if ( $this->sortField == 'name' && $this->sortDirection == '_desc' ) {
			$sub_folders = array_reverse($sub_folders);
		}

		$ret .= $this->_buildFoldersXML($sub_folders, 'folder');

		return $ret;
	}

	/**
	 * Build XML, that will output folders for FCKEditor
	 *
	 * @param Array $sub_folders
	 * @param string $xml_node
	 * @return string
	 */
	protected function _buildFoldersXML($sub_folders, $xml_node)
	{
		$ret = '';

		foreach ($sub_folders as $sub_folder) {
			$ret .= '<' . $xml_node . ' path="' . $this->folder . "/" . $sub_folder . '">' . $sub_folder . '</' . $xml_node . '>' . "\n";
		}

		return $ret;
	}

	/**
	 * Transforms filesize in bytes into kilobytes
	 *
	 * @param int $size
	 * @return int
	 * @access protected
	 */
	protected function CalculateFileSize($size)
	{
		if ( $size > 0 ) {
			$size = round($size / 1024);
			$size = ($size < 1) ? 1 : $size;
		}

		return $size;
	}

	/**
	 * Detects icon for given file extension
	 *
	 * @param string $file
	 * @return string
	 * @access protected
	 */
	protected function CheckIconType($file)
	{
		$ext = strtolower( pathinfo($file, PATHINFO_EXTENSION) );

		return $ext && in_array($ext, $this->Config['ExtensionIcons']) ? $ext : 'default.icon';
	}

	/**
	 * Build one file xml node
	 *
	 * @param int $size
	 * @param string $url
	 * @param string $icon
	 * @param string $date
	 * @param string $file_name
	 * @return string
	 */
	protected function _buildFileXml($size,$url,$icon,$date,$file_name)
	{
		return '<file size="' . $size . '" url="' . $url . '" icon="' . $icon . '" date="' . $date . '">' . $file_name . '</file>' . "\n";
	}

	/**
	 * Returns xml containing list of files in current folder
	 *
	 * @return string
	 * @access public
	 */
	public function PrintFiles()
	{
		$files_dir = WRITEABLE . '/user_files/' . $this->folder . '/';
		$files_url = BASE_PATH . str_replace(DIRECTORY_SEPARATOR, '/', WRITEBALE_BASE) . '/user_files/' . $this->folder . '/';
		$aFiles = $this->ReadFiles($files_dir);
		$ret = '';
		$date_format = "m/d/Y h:i A";
		natcasesort($aFiles);

		if ( $this->sortField == 'name' && $this->sortDirection == '_desc' ) {
			$aFiles = array_reverse($aFiles, TRUE);
		}

		$aFilesSize = $aFilesDate = Array ();

		foreach ($aFiles as $k => $v) {
			$aFilesSize[$k] = filesize($files_dir . $v);
			$aFilesDate[$k] = filectime($files_dir . $v);
		}

		if ( $this->sortField == 'name' ) {
			foreach ($aFiles as $k => $file) {
				$size = $this->CalculateFileSize($aFilesSize[$k]);
				$date = date($date_format, $aFilesDate[$k]);
				$icon = $this->CheckIconType($file);
				$ret .= $this->_buildFileXml($size, $files_url . $file, $icon, $date, $file);
			}
		}

		if ( $this->sortField == 'date' ) {
			asort($aFilesDate);
			if ( $this->sortDirection == '_desc' ) {
				$aFilesDate = array_reverse($aFilesDate, TRUE);
			}

			foreach ($aFilesDate as $k => $date) {
				$size = $this->CalculateFileSize($aFilesSize[$k]);
				$file = $aFiles[$k];
				$date = date($date_format, $date);
				$icon = $this->CheckIconType($file);
				$ret .= $this->_buildFileXml($size, $files_url . $file, $icon, $date, $file);
			}
		}

		if ( $this->sortField == 'size' ) {
			asort($aFilesSize);
			if ( $this->sortDirection == '_desc' ) {
				$aFilesSize = array_reverse($aFilesSize, TRUE);
			}

			foreach ($aFilesSize as $k => $size) {
				$size = $this->CalculateFileSize($size);
				$file = $aFiles[$k];
				$date = date($date_format, $aFilesDate[$k]);
				$icon = $this->CheckIconType($file);
				$ret .= $this->_buildFileXml($size, $files_url . $file, $icon, $date, $file);
			}
		}

		return $ret;
	}

	function UploadFile()
	{
		$upload_dir = $this->Application->GetVar('upload_dir');
		$type = explode('/', $upload_dir);
		$type = $type[0];
		$sServerDir =  WRITEABLE . '/user_files/' . $upload_dir . '/';

		$aUpFile = $_FILES['NewFile'];
		$sFileName = $aUpFile['name'];
		$sOriginalFileName = $aUpFile['name'];
		$sExtension = strtolower(substr( $sFileName, ( strrpos($sFileName, '.') + 1 ) ) );
		$sErrorNumber = 0;

		if ( isset( $_FILES['NewFile'] ) && !is_null( $_FILES['NewFile']['tmp_name'] ) )
		{
			if (in_array($sExtension, $this->Config['AllowedExtensions'][$type]))
			{
				if (!$aUpFile['error']) {
					$iCounter = 0 ;
					while ( true )
					{
						$sFilePath = $sServerDir . $sFileName;
						if ( is_file( $sFilePath ) )
						{
							$iCounter++ ;
							$sFileName = $this->RemoveExtension( $sOriginalFileName ) . '(' . $iCounter . ').' . $sExtension;
							$sErrorNumber = '201';
						}
						else
						{
							// Turn off all error reporting.
							error_reporting( 0 ) ;

							// Enable error tracking to catch the error.
							ini_set( 'track_errors', '1' );

							move_uploaded_file( $aUpFile['tmp_name'], $sFilePath );
							$sErrorMsg = $php_errormsg;

							// Restore the configurations.
							ini_restore( 'track_errors' );
							ini_restore( 'error_reporting' );

							if ( is_file( $sFilePath ) ) {
								$oldumask = umask(0);
								chmod( $sFilePath, 0666 );
								umask( $oldumask );
							}
							break ;
						}
					}
				}
			}
			else {
				$sErrorNumber = '203';
			}
		}
		else {
			$sErrorNumber = '202' ;
		}

		echo '<script type="text/javascript">' ;
		echo 'window.parent.frames["frmUpload"].OnUploadCompleted(' . $sErrorNumber . ',"' . str_replace( '"', '\\"', $sFileName ) . '") ;' ;
		echo '</script>' ;
	}

	function RemoveExtension( $fileName )
	{
		return substr( $fileName, 0, strrpos( $fileName, '.' ) ) ;
	}

	/**
	 * Returns transit parameters, that should be passed to every used CKEditor instance
	 *
	 * @param Array $tag_params
	 * @return Array
	 */
	public function getTransitParams($tag_params = Array ())
	{
		$ret = Array ();
		$transit_params = Array ('bgcolor' => '', 'body_class' => '', 'body_id' => '');

		foreach ($transit_params as $param_name => $default_value) {
			$param_value = isset($tag_params[$param_name]) ? $tag_params[$param_name] : $this->Application->GetVar($param_name);

			if ( $param_value || $default_value ) {
				$ret[$param_name] = $param_value ? $param_value : $default_value;
			}
		}

		return $ret;
	}
}