/cms/utils/file_utils.php
PHP | 373 lines | 267 code | 61 blank | 45 comment | 73 complexity | b369581f4d0a957596dbfe082f6d6e40 MD5 | raw file
Possible License(s): BSD-2-Clause, GPL-2.0, LGPL-2.1
- <?php
-
- if( !defined("SITE_ID") ) {
- require_once('../accesscheck.php');
- }
-
- $fileUtils = new FileUtils();
-
- if( isset($_POST['action']) && $_POST['action'] == "save_file" && isset($_POST['FilePath']) ) {
-
- $fileUtils->saveFileContent( kan_fix_path($_POST['FilePath']), $_POST['EditorContent'] );
- }
-
- if( isset($_POST['action']) && $_POST['action'] == "show_file" && $_POST['FilePath'] ) {
- $content = file_get_contents( kan_fix_path($_POST['FilePath']) );
- $mimeType = isset($_POST['mimeType']) ? $_POST['mimeType'] : 'text/php';
- $content = htmlentities($content);
- $fileUtils->getEditorForContent($content, $mimeType);
- }
-
- if( isset($_POST['action']) && $_POST['action'] == "delete_file" && isset($_POST['FilePath']) ) {
- // check if the file can found without redirection
- if( file_exists($_POST['FilePath']) ) {
- $fileUtils->deleteFile( $_POST['FilePath'] );
-
- // redirect outside the utils folder, especially when running via ajax
- } else if( file_exists( kan_fix_path($_POST['FilePath']) ) ) {
- $fileUtils->deleteFile( kan_fix_path($_POST['FilePath']) );
-
- }
- }
-
- class FileUtils {
-
- public $mimeTypes = array(
- "js" => "text/javascript",
- "css" => "text/css",
- "php" => "text/php",
- "html" => "text/html",
- "htm" => "text/html",
- "xml" => "text/xml",
- "json" => "text/javascript"
- );
-
- public $webExtensions = array(
- "js" => "javascript",
- "css" => "css",
- "php" => "php",
- "html" => "html",
- "htm" => "html",
- "xml" => "xml",
- "gif" => "gif",
- "jpg" => "jpg",
- "png" => "png",
- "swf" => "swf",
- "json" => "json"
- );
-
- public function printScripts() { ?>
- <link type="text/css" href="../cms/utils/file_utils.css" rel="stylesheet" />
- <script type="text/javascript" src="../cms/utils/file_utils.js"></script>
- <script type="text/javascript" src="../cms/scripts/code_mirror/js/codemirror.js"></script>
- <?php
- }
-
- public function getFileEditInfo($filePath, $mimeType = 'text/php') {
-
- $file_type = is_dir($filePath) ? "Folder" : "File";
-
- if( is_writable($filePath) ) {
- echo "<span class='cms-file-writable'>$file_type Is Writable</span>";
-
- if( !is_dir($filePath) ) {
- echo " | <a href=\"javascript:file_utils.showOverlayedEditor('$filePath', '$mimeType');\">Edit File</a>";
- }
- } else {
- echo "<span class='cms-file-readonly'>File Is Readonly</span>";
- }
- }
-
- public function saveFileContent($filePath, $contentData) {
-
- if( is_writable($filePath) ) {
- $data = stripslashes($contentData); // remove possible escaped characters
- $data = htmlentities($data); // encode the data as HTML
-
- file_put_contents( $filePath, "" . html_entity_decode($data) . "" );
- }
- }
-
- public function generateFolderTree($folder) {
- if( $folder == '' || $folder == NULL ) {
- return;
- }
-
- $dirname = basename($folder);
- echo "<div id='dir_tree' class='dir_tree'>\n";
- echo "<ul class='dir_group'><li class='dir_name'>"
- . "<div >"
- . " <div class='name_col'><span>$dirname</span></div>"
- . " <!--<div class='options_col'><a href='#'>Add</a> | <a href='#'>Delete</a></div>--> "
- . "</div>";
- $this->traverseDirTree($folder, FALSE);
- echo "</li></ul>\n";
- echo "</div>\n"; ?>
-
- <script type="text/javascript">
- pageManager.addLoadEvent( file_utils.attachFolderHandlers );
- </script><?php
- }
-
-
- public function traverseDirTree($path = '.', $isSub = TRUE) {
- $handle = opendir($path);
-
- if ( $handle ) {
- $collapsed = ($isSub == TRUE) ? "collapsed" : "expanded";
- echo "<ul class='dir_group $collapsed'>";
-
- $queuedir = array();
- $queuefile = array();
-
- while (false !== ($file = readdir($handle))) {
- if (is_dir($path.$file) && $file != '.' && $file !='..')
- $queuedir[] = $file;
- else if ($file != '.' && $file !='..')
- $queuefile[] = $file;
- }
-
- sort($queuedir);
- sort($queuefile);
-
- $this->printSubDir($queuedir, $path);
- $this->printQueue($queuefile, $path);
-
- echo "</ul>";
- }
- }
-
- private function printSubDir($queue, $path) {
- foreach ($queue as $dir) {
- echo "<li class='dir_name'>"
- . "<div >"
- . " <div class='name_col'><span>$dir</span></div>"
- . " <!--<div class='options_col'>Add | Delete</div>-->"
- . "</div>";
- $this->traverseDirTree($path.$dir."/");
- echo "</li>";
- }
- }
-
- private function printQueue($queue, $path) {
- foreach ($queue as $file) {
- $filePath = $path.$file;
- $extension = substr($file, strrpos($file,".") + 1);
-
- // if file is writable and file type is editable
- if( is_writable($filePath) && array_key_exists($extension, $this->mimeTypes) ) {
- $mimeType = $this->mimeTypes[$extension];
- echo "<li class='file_name'>"
- . "<div class='name_col'>"
- . " <a href=\"javascript:file_utils.showOverlayedEditor('$filePath', '$mimeType'); \">$file</a>"
- . "</div>"
- . "<div class='options_col'>"
- . " <a href=\"javascript:file_utils.showOverlayedEditor('$filePath', '$mimeType'); \">Edit</a> | "
- . " <a href=\"#\" onclick=\"file_utils.deleteFile('$filePath', this); return false;\">Delete</a> "
- . "</div>"
- . "</li>";
-
- // if is web related document
- } else if( array_key_exists($extension, $this->webExtensions) ) {
- echo "<li class='file_name'>$file</li>";
- } else {
- //echo "<li class='file_name'>$file</li>";
- }
- }
- }
-
- public function deleteFile($filePath, $canRemoveDir = false) {
- if( file_exists($filePath) ) {
- if( is_dir($filePath) && $canRemoveDirr ) {
- $this->rmdirr($filePath);
- } else {
- unlink($filePath);
- }
- }
- }
-
- public function rmdirr($dirname) {
- // Sanity check
- if (!file_exists($dirname)) {
- return false;
- }
-
- // Simple delete for a file
- if (is_file($dirname)) {
- return unlink($dirname);
- }
-
- // Loop through the folder
- $dir = dir($dirname);
- while (false !== $entry = $dir->read()) {
- // Skip pointers
- if ($entry == '.' || $entry == '..') {
- continue;
- }
-
- // Recurse
- $this->rmdirr("$dirname/$entry");
- }
-
- // Clean up
- $dir->close();
- return rmdir($dirname);
- }
-
- public function getEditorForContent($content = '', $mimeType = 'text/php') {
- if( $content == '' ) {
- $content .= "<?php \n";
- $content .= " //TODO: your PHP code goes here\n";
- $content .= "?>";
- } ?>
-
- <div style="height: 520px; position: relative; overflow: hidden;">
- <textarea cols="10" rows="3" id='EditorContent' name='EditorContent' style="width: 100%; height: 100%;"><?php echo $content; ?></textarea>
-
- <script type="text/javascript">
- pageManager.addLoadEvent( function() {
- file_utils.codeEditor = CodeMirror.fromTextArea('EditorContent', {
-
- parserfile: ["parsexml.js", "parsecss.js", "tokenizejavascript.js", "parsejavascript.js", "parsehtmlmixed.js",
- "../contrib/php/js/tokenizephp.js", "../contrib/php/js/parsephp.js",
- "../contrib/php/js/parsephphtmlmixed.js"],
- stylesheet: ["../cms/scripts/code_mirror/css/xmlcolors.css",
- "../cms/scripts/code_mirror/css/jscolors.css",
- "../cms/scripts/code_mirror/css/csscolors.css",
- "../cms/scripts/code_mirror/contrib/php/css/phpcolors.css"],
- path: "../cms/scripts/code_mirror/js/",
- continuousScanning: 500,
- textWrapping: false
- });
- });
- </script>
- </div><?php
- }
-
-
- public function extractZipArchive($filePath, $destFolder = '') {
- // create object
- $zip = new ZipArchive() ;
-
- // open archive
- if ($zip->open( $destZipFile ) !== TRUE) {
- die ('Could not open archive');
- }
-
- // if the destFolder is not supplied, then we'll need to extract the file to
- // same directory.
- if( $destFolder == '') {
- $destFolder = dirname($filePath);
- }
-
- // extract contents to destination directory
- $zip->extractTo($destFolder);
-
- // close archive
- $zip->close();
- }
-
- /**
- * Copy file or folder from source to destination, it can do
- * recursive copy as well and is very smart
- * It recursively creates the dest file or directory path if there weren't exists
- * Situtaions :
- * - Src:/home/test/file.txt ,Dst:/home/test/b ,Result:/home/test/b -> If source was file copy file.txt name with b as name to destination
- * - Src:/home/test/file.txt ,Dst:/home/test/b/ ,Result:/home/test/b/file.txt -> If source was file Creates b directory if does not exsits and copy file.txt into it
- * - Src:/home/test ,Dst:/home/ ,Result:/home/test/** -> If source was directory copy test directory and all of its content into dest
- * - Src:/home/test/ ,Dst:/home/ ,Result:/home/**-> if source was direcotry copy its content to dest
- * - Src:/home/test ,Dst:/home/test2 ,Result:/home/test2/** -> if source was directoy copy it and its content to dest with test2 as name
- * - Src:/home/test/ ,Dst:/home/test2 ,Result:->/home/test2/** if source was directoy copy it and its content to dest with test2 as name
- * @todo
- * - Should have rollback technique so it can undo the copy when it wasn't successful
- * - Auto destination technique should be possible to turn off
- * - Supporting callback function
- * - May prevent some issues on shared enviroments : http://us3.php.net/umask
- * @param $source //file or folder
- * @param $dest ///file or folder
- * @param $options //folderPermission,filePermission
- * @return boolean
- */
- public function smartCopy($source, $dest, $options=array('folderPermission'=>0755,'filePermission'=>0755))
- {
- $result=false;
-
- if (is_file($source)) {
- if ($dest[strlen($dest)-1]=='/') {
- if (!file_exists($dest)) {
- cmfcDirectory::makeAll($dest,$options['folderPermission'],true);
- }
- $__dest=$dest."/".basename($source);
- } else {
- $__dest=$dest;
- }
- $result=copy($source, $__dest);
- chmod($__dest,$options['filePermission']);
-
- } elseif(is_dir($source)) {
- if ($dest[strlen($dest)-1]=='/') {
- if ($source[strlen($source)-1]=='/') {
- //Copy only contents
- } else {
- //Change parent itself and its contents
- $dest=$dest.basename($source);
- @mkdir($dest);
- chmod($dest,$options['filePermission']);
- }
- } else {
- if ($source[strlen($source)-1]=='/') {
- //Copy parent directory with new name and all its content
- @mkdir($dest,$options['folderPermission']);
- chmod($dest,$options['filePermission']);
- } else {
- //Copy parent directory with new name and all its content
- @mkdir($dest,$options['folderPermission']);
- chmod($dest,$options['filePermission']);
- }
- }
-
- $dirHandle=opendir($source);
- while($file=readdir($dirHandle))
- {
- if($file!="." && $file!="..")
- {
- if(!is_dir($source."/".$file)) {
- $__dest=$dest."/".$file;
- } else {
- $__dest=$dest."/".$file;
- }
- //echo "$source/$file ||| $__dest<br />";
- $result = $this->smartCopy($source."/".$file, $__dest, $options);
- }
- }
- closedir($dirHandle);
-
- } else {
- $result=false;
- }
- return $result;
- }
-
- public function encodeUrlParam ( $string ) {
- $string = trim($string);
-
- if ( ctype_digit($string) ) {
- return $string;
-
- } else {
- // replace accented chars
- $accents = '/&([A-Za-z]{1,2})(grave|acute|circ|cedil|uml|lig);/';
- $string_encoded = htmlentities($string,ENT_NOQUOTES,'UTF-8');
-
- $string = preg_replace($accents,'$1',$string_encoded);
-
- // clean out the rest
- $replace = array('([\40])','([^a-zA-Z0-9-])','(-{2,})');
- $with = array('-','','-');
- $string = preg_replace($replace,$with,$string);
- }
-
- return strtolower($string);
- }
- }
- ?>