linea21-externals
[ class tree: linea21-externals ] [ index: linea21-externals ] [ all elements ]

Source for file filemanager.class.php

Documentation is available at filemanager.class.php

  1. <?php
  2. /**
  3.  *    Filemanager PHP class
  4.  *
  5.  *    filemanager.class.php
  6.  *    class for the filemanager.php connector
  7.  *
  8.  *    @license    MIT License
  9.  *    @author        Riaan Los <mail (at) riaanlos (dot) nl>
  10.  *    @author        Simon Georget <simon (at) linea21 (dot) com>
  11.  *    @copyright    Authors
  12.  *  @package     linea21.externals
  13.  *  @subpackage Filemanager
  14.  */
  15.  
  16. class Filemanager {
  17.  
  18.   protected $config = array();
  19.   protected $language = array();
  20.   protected $get = array();
  21.   protected $post = array();
  22.   protected $properties = array();
  23.   protected $item = array();
  24.   protected $languages = array();
  25.   protected $root = '';
  26.   protected $doc_root = '';
  27.  
  28.   public function __construct($config) {
  29.     $this->config = $config;
  30.     $this->root = dirname(dirname(dirname(__FILE__))).DIRECTORY_SEPARATOR;
  31.     $this->properties = array(
  32.               'Date Created'=>null,
  33.               'Date Modified'=>null,
  34.               'Height'=>null,
  35.               'Width'=>null,
  36.               'Size'=>null
  37.     );
  38.     if (isset($this->config['doc_root'])) {
  39.       $this->doc_root = $this->config['doc_root'];
  40.     } else {
  41.       $this->doc_root = $_SERVER['DOCUMENT_ROOT'];
  42.     }
  43.  
  44.     $this->setParams();
  45.     $this->availableLanguages();
  46.     $this->loadLanguageFile();
  47.   }
  48.  
  49.   public function error($string,$textarea=false) {
  50.     $array = array(
  51.             'Error'=>$string,
  52.             'Code'=>'-1',
  53.             'Properties'=>$this->properties
  54.     );
  55.     if($textarea) {
  56.       echo '<textarea>' . json_encode($array) . '</textarea>';
  57.     } else {
  58.       echo json_encode($array);
  59.     }
  60.     die();
  61.   }
  62.  
  63.   public function lang($string) {
  64.     if(isset($this->language[$string]) && $this->language[$string]!='') {
  65.       return $this->language[$string];
  66.     } else {
  67.       return 'Language string error on ' . $string;
  68.     }
  69.   }
  70.  
  71.   public function getvar($var) {
  72.     if(!isset($_GET[$var]) || $_GET[$var]=='') {
  73.       $this->error(sprintf($this->lang('INVALID_VAR'),$var));
  74.     } else {
  75.       $this->get[$var] = $this->sanitize($_GET[$var]);
  76.       return true;
  77.     }
  78.   }
  79.   public function postvar($var) {
  80.     if(!isset($_POST[$var]) || $_POST[$var]=='') {
  81.       $this->error(sprintf($this->lang('INVALID_VAR'),$var));
  82.     } else {
  83.       $this->post[$var] = $_POST[$var];
  84.       return true;
  85.     }
  86.   }
  87.  
  88.   public function getinfo() {
  89.     $this->item = array();
  90.     $this->item['properties'] = $this->properties;
  91.     $this->get_file_info();
  92.  
  93.     $array = array(
  94.             'Path'=> $this->get['path'],
  95.             'Filename'=>$this->item['filename'],
  96.             'File Type'=>$this->item['filetype'],
  97.             'Preview'=>$this->item['preview'],
  98.             'Properties'=>$this->item['properties'],
  99.             'Error'=>"",
  100.             'Code'=>0
  101.     );
  102.     return $array;
  103.   }
  104.  
  105.   public function getfolder() {
  106.     $array = array();
  107.     $filesDir = array();
  108.  
  109.     $current_path = $this->doc_root . rawurldecode($this->get['path']);
  110.     if(!is_dir($current_path)) {
  111.       $this->error(sprintf($this->lang('DIRECTORY_NOT_EXIST'),$this->get['path']));
  112.     }
  113.     if(!$handle = opendir($current_path)) {
  114.       $this->error(sprintf($this->lang('UNABLE_TO_OPEN_DIRECTORY'),$this->get['path']));
  115.     } else {
  116.       while (false !== ($file = readdir($handle))) {
  117.         if($file != "." && $file != "..") {
  118.           array_push($filesDir, $file);
  119.         }
  120.       }
  121.       closedir($handle);
  122.  
  123.       sort($filesDir); // sorting by names
  124.  
  125.       // Sort files by modified time, latest to earliest
  126.       // Use SORT_ASC in place of SORT_DESC for earliest to latest
  127.       //      array_multisort(
  128.       //        array_map( 'filemtime', $filesDir ),
  129.       //        SORT_NUMERIC,
  130.       //        SORT_DESC,
  131.       //        $filesDir
  132.       //      );
  133.  
  134.       foreach($filesDir as $file) {
  135.  
  136.         if(is_dir($current_path . $file)) {
  137.           if(!in_array($file, $this->config['unallowed_dirs'])) {
  138.             $array[$this->get['path'] . $file .'/'] = array(
  139.                         'Path'=> $this->get['path'] . $file .'/',
  140.                         'Filename'=>$file,
  141.                         'File Type'=>'dir',
  142.                         'Preview'=> $this->config['icons']['path'] . $this->config['icons']['directory'],
  143.                         'Properties'=>array(
  144.                             'Date Created'=>null,
  145.                             'Date Modified'=>null,
  146.                             'Height'=>null,
  147.                             'Width'=>null,
  148.                             'Size'=>null
  149.             ),
  150.                         'Error'=>"",
  151.                         'Code'=>0
  152.             );
  153.           }
  154.         } else if (!in_array($file, $this->config['unallowed_files'])) {
  155.           $this->item = array();
  156.           $this->item['properties'] = $this->properties;
  157.           $this->get_file_info($this->get['path'] . $file);
  158.            
  159.           if(!isset($this->params['type']) || (isset($this->params['type']) && strtolower($this->params['type'])=='images' && in_array(strtolower($this->item['filetype']),$this->config['images']))) {
  160.             if($this->config['upload']['imagesonly']== false || ($this->config['upload']['imagesonly']== true && in_array(strtolower($this->item['filetype']),$this->config['images']))) {
  161.               $array[$this->get['path'] . $file] = array(
  162.                             'Path'=>$this->get['path'] . $file,
  163.                             'Filename'=>$this->item['filename'],
  164.                             'File Type'=>$this->item['filetype'],
  165.                             'Preview'=>$this->item['preview'],
  166.                             'Properties'=>$this->item['properties'],
  167.                             'Error'=>"",
  168.                             'Code'=>0
  169.               );
  170.             }
  171.           }
  172.         }
  173.       }
  174.     }
  175.     
  176.     return $array;
  177.   }
  178.  
  179.   public function rename() {
  180.  
  181.     $suffix='';
  182.  
  183.  
  184.     if(substr($this->get['old'],-1,1)=='/') {
  185.       $this->get['old'] = substr($this->get['old'],0,(strlen($this->get['old'])-1));
  186.       $suffix='/';
  187.     }
  188.     $tmp = explode('/',$this->get['old']);
  189.     $filename = $tmp[(sizeof($tmp)-1)];
  190.     $path = str_replace('/' . $filename,'',$this->get['old']);
  191.  
  192.     if(file_exists ($this->doc_root . $path . '/' . $this->get['new'])) {
  193.       if($suffix=='/' && is_dir($this->doc_root . $path . '/' . $this->get['new'])) {
  194.         $this->error(sprintf($this->lang('DIRECTORY_ALREADY_EXISTS'),$this->get['new']));
  195.       }
  196.       if($suffix=='' && is_file($this->doc_root . $path . '/' . $this->get['new'])) {
  197.         $this->error(sprintf($this->lang('FILE_ALREADY_EXISTS'),$this->get['new']));
  198.       }
  199.     }
  200.  
  201.     if(!rename($this->doc_root . $this->get['old'],$this->doc_root . $path . '/' . $this->get['new'])) {
  202.       if(is_dir($this->get['old'])) {
  203.         $this->error(sprintf($this->lang('ERROR_RENAMING_DIRECTORY'),$filename,$this->get['new']));
  204.       } else {
  205.         $this->error(sprintf($this->lang('ERROR_RENAMING_FILE'),$filename,$this->get['new']));
  206.       }
  207.     }
  208.     $array = array(
  209.             'Error'=>"",
  210.             'Code'=>0,
  211.             'Old Path'=>$this->get['old'],
  212.             'Old Name'=>$filename,
  213.             'New Path'=>$path . '/' . $this->get['new'].$suffix,
  214.             'New Name'=>$this->get['new']
  215.     );
  216.     return $array;
  217.   }
  218.  
  219.   public function delete() {
  220.  
  221.     if(is_dir($this->doc_root . rawurldecode($this->get['path']))) {
  222.       $this->unlinkRecursive($this->doc_root . rawurldecode($this->get['path']));
  223.       $array = array(
  224.                 'Error'=>"",
  225.                 'Code'=>0,
  226.                 'Path'=>$this->get['path']
  227.       );
  228.       return $array;
  229.     } else if(file_exists($this->doc_root . rawurldecode($this->get['path']))) {
  230.       unlink($this->doc_root . rawurldecode($this->get['path']));
  231.       $array = array(
  232.                 'Error'=>"",
  233.                 'Code'=>0,
  234.                 'Path'=>$this->get['path']
  235.       );
  236.       return $array;
  237.     } else {
  238.       $this->error(sprintf($this->lang('INVALID_DIRECTORY_OR_FILE')));
  239.     }
  240.   }
  241.  
  242.   public function add() {
  243.     $this->setParams();
  244.     if(!isset($_FILES['newfile']) || !is_uploaded_file($_FILES['newfile']['tmp_name'])) {
  245.       $this->error(sprintf($this->lang('INVALID_FILE_UPLOAD')),true);
  246.     }
  247.     if(($this->config['upload']['size']!=false && is_numeric($this->config['upload']['size'])) && ($_FILES['newfile']['size'] > ($this->config['upload']['size'] * 1024 * 1024))) {
  248.       $this->error(sprintf($this->lang('UPLOAD_FILES_SMALLER_THAN'),$this->config['upload']['size'] . 'Mb'),true);
  249.     }
  250.     if($this->config['upload']['imagesonly'] || (isset($this->params['type']) && strtolower($this->params['type'])=='images')) {
  251.       if(!($size = @getimagesize($_FILES['newfile']['tmp_name']))){
  252.         $this->error(sprintf($this->lang('UPLOAD_IMAGES_ONLY')),true);
  253.       }
  254.       if(!in_array($size[2], array(1, 2, 3, 7, 8))) {
  255.         $this->error(sprintf($this->lang('UPLOAD_IMAGES_TYPE_JPEG_GIF_PNG')),true);
  256.       }
  257.     }
  258.     $_FILES['newfile']['name'] = $this->cleanString($_FILES['newfile']['name'],array('.','-'));
  259.     if(!$this->config['upload']['overwrite']) {
  260.       $_FILES['newfile']['name'] = $this->checkFilename($this->doc_root . $this->post['currentpath'],$_FILES['newfile']['name']);
  261.     }
  262.     move_uploaded_file($_FILES['newfile']['tmp_name'], $this->doc_root . $this->post['currentpath'] . $_FILES['newfile']['name']);
  263.     chmod($this->doc_root . $this->post['currentpath'] . $_FILES['newfile']['name'], 0644);
  264.  
  265.     $response = array(
  266.             'Path'=>$this->post['currentpath'],
  267.             'Name'=>$_FILES['newfile']['name'],
  268.             'Error'=>"",
  269.             'Code'=>0
  270.     );
  271.     echo '<textarea>' . json_encode($response) . '</textarea>';
  272.     die();
  273.   }
  274.  
  275.   public function addfolder() {
  276.     if(is_dir($this->doc_root . $this->get['path'] . $this->get['name'])) {
  277.       $this->error(sprintf($this->lang('DIRECTORY_ALREADY_EXISTS'),$this->get['name']));
  278.        
  279.     }
  280.     $newdir = $this->cleanString($this->get['name']);
  281.     if(!mkdir($this->doc_root . $this->get['path'] . $newdir,0755)) {
  282.       $this->error(sprintf($this->lang('UNABLE_TO_CREATE_DIRECTORY'),$newdir));
  283.     }
  284.     $array = array(
  285.             'Parent'=>$this->get['path'],
  286.             'Name'=>$this->get['name'],
  287.             'Error'=>"",
  288.             'Code'=>0
  289.     );
  290.     return $array;
  291.   }
  292.  
  293.   public function download() {
  294.  
  295.     if(isset($this->get['path']) && file_exists($this->doc_root .rawurldecode($this->get['path']))) {
  296.       header("Content-type: application/force-download");
  297.       header('Content-Disposition: inline; filename="' . basename(rawurldecode($this->get['path'])) . '"');
  298.       header("Content-Transfer-Encoding: Binary");
  299.       header("Content-length: ".filesize($this->doc_root . rawurldecode($this->get['path'])));
  300.       header('Content-Type: application/octet-stream');
  301.       header('Content-Disposition: attachment; filename="' . basename(rawurldecode($this->get['path'])) . '"');
  302.       readfile($this->doc_root . $this->get['path']);
  303.       exit();
  304.     } else {
  305.       $this->error(sprintf($this->lang('FILE_DOES_NOT_EXIST'),rawurldecode($this->get['path'])));
  306.     }
  307.   }
  308.  
  309.   public function preview() {
  310.  
  311.     if(isset($this->get['path']) && file_exists($this->doc_root . rawurldecode($this->get['path']))) {
  312.       header("Content-type: image/" .$ext = pathinfo(rawurldecode($this->get['path']), PATHINFO_EXTENSION));
  313.       header("Content-Transfer-Encoding: Binary");
  314.       header("Content-length: ".filesize($this->doc_root . rawurldecode($this->get['path'])));
  315.       header('Content-Disposition: inline; filename="' . basename(rawurldecode($this->get['path'])) . '"');
  316.       readfile($this->doc_root . rawurldecode($this->get['path']));
  317.       exit();
  318.     } else {
  319.       $this->error(sprintf($this->lang('FILE_DOES_NOT_EXIST'),rawurldecode($this->get['path'])));
  320.     }
  321.   }
  322.  
  323.   private function setParams() {
  324.     $tmp = (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/');
  325.     $tmp = explode('?',$tmp);
  326.     $params = array();
  327.     if(isset($tmp[1]) && $tmp[1]!='') {
  328.       $params_tmp = explode('&',$tmp[1]);
  329.       if(is_array($params_tmp)) {
  330.         foreach($params_tmp as $value) {
  331.           $tmp = explode('=',$value);
  332.           if(isset($tmp[0]) && $tmp[0]!='' && isset($tmp[1]) && $tmp[1]!='') {
  333.             $params[$tmp[0]] = $tmp[1];
  334.           }
  335.         }
  336.       }
  337.     }
  338.     $this->params = $params;
  339.   }
  340.  
  341.  
  342.   private function get_file_info($path='',$return=array()) {
  343.     if($path=='') {
  344.       $path = rawurldecode($this->get['path']);
  345.     }
  346.     $tmp = explode('/',$path);
  347.     $this->item['filename'] = $tmp[(sizeof($tmp)-1)];
  348.  
  349.     $tmp = explode('.',$this->item['filename']);
  350.     $this->item['filetype'] = $tmp[(sizeof($tmp)-1)];
  351.     $this->item['filemtime'] = filemtime($this->doc_root . $path);
  352.     $this->item['filectime'] = filectime($this->doc_root . $path);
  353.  
  354.     $this->item['preview'] = $this->config['icons']['path'] . $this->config['icons']['default'];
  355.  
  356.     if(is_dir($this->doc_root . $path)) {
  357.        
  358.       $this->item['preview'] = $this->config['icons']['path'] . $this->config['icons']['directory'];
  359.        
  360.     } else if(in_array(strtolower($this->item['filetype']),$this->config['images'])) {
  361.        
  362.       $this->item['preview'] = 'connectors/php/filemanager.php?mode=preview&path=' . rawurlencode($path);
  363.       //if(isset($get['getsize']) && $get['getsize']=='true') {
  364.       $this->item['properties']['Size'] = filesize($this->doc_root . $path);
  365.       if ($this->item['properties']['Size']) {
  366.         list($width, $height, $type, $attr) = getimagesize($this->doc_root . $path);
  367.       } else {
  368.         $this->item['properties']['Size'] = 0;
  369.         list($width, $height) = array(0, 0);
  370.       }
  371.       $this->item['properties']['Height'] = $height;
  372.       $this->item['properties']['Width'] = $width;
  373.       $this->item['properties']['Size'] = filesize($this->doc_root . $path);
  374.       //}
  375.        
  376.     } else if(file_exists($this->root . $this->config['icons']['path'] . strtolower($this->item['filetype']) . '.png')) {
  377.        
  378.       $this->item['preview'] = $this->config['icons']['path'] . strtolower($this->item['filetype']) . '.png';
  379.       $this->item['properties']['Size'] = filesize($this->doc_root . $path);
  380.       if (!$this->item['properties']['Size']) $this->item['properties']['Size'] = 0;
  381.        
  382.     }
  383.  
  384.     $this->item['properties']['Date Modified'] = date($this->config['date'], $this->item['filemtime']);
  385.     //$return['properties']['Date Created'] = date($config['date'], $return['filectime']); // PHP cannot get create timestamp
  386.   }
  387.  
  388.   private function unlinkRecursive($dir,$deleteRootToo=true) {
  389.     if(!$dh = @opendir($dir)) {
  390.       return;
  391.     }
  392.     while (false !== ($obj = readdir($dh))) {
  393.       if($obj == '.' || $obj == '..') {
  394.         continue;
  395.       }
  396.        
  397.       if (!@unlink($dir . '/' . $obj)) {
  398.         $this->unlinkRecursive($dir.'/'.$obj, true);
  399.       }
  400.     }
  401.  
  402.     closedir($dh);
  403.  
  404.     if ($deleteRootToo) {
  405.       @rmdir($dir);
  406.     }
  407.     return;
  408.   }
  409.  
  410.   private function cleanString($string, $allowed = array()) {
  411.     $allow = null;
  412.  
  413.     if (!empty($allowed)) {
  414.       foreach ($allowed as $value) {
  415.         $allow .= "\\$value";
  416.       }
  417.     }
  418.  
  419.     $mapping = array(
  420.         'Š'=>'S', 'š'=>'s', 'Đ'=>'Dj', 'đ'=>'dj', 'Ž'=>'Z', 'ž'=>'z', 'Č'=>'C', 'č'=>'c', 'Ć'=>'C', 'ć'=>'c',
  421.         'À'=>'A', 'Á'=>'A', 'Â'=>'A', 'Ã'=>'A', 'Ä'=>'A', 'Å'=>'A', 'Æ'=>'A', 'Ç'=>'C', 'È'=>'E', 'É'=>'E',
  422.         'Ê'=>'E', 'Ë'=>'E', 'Ì'=>'I', 'Í'=>'I', 'Î'=>'I', 'Ï'=>'I', 'Ñ'=>'N', 'Ò'=>'O', 'Ó'=>'O', 'Ô'=>'O',
  423.         'Õ'=>'O', 'Ö'=>'O', 'Ő'=>'O', 'Ø'=>'O', 'Ù'=>'U', 'Ú'=>'U', 'Û'=>'U', 'Ü'=>'U', 'Ű'=>'U', 'Ý'=>'Y',
  424.         'Þ'=>'B', 'ß'=>'Ss','à'=>'a', 'á'=>'a', 'â'=>'a', 'ã'=>'a', 'ä'=>'a', 'å'=>'a', 'æ'=>'a', 'ç'=>'c',
  425.         'è'=>'e', 'é'=>'e', 'ê'=>'e', 'ë'=>'e', 'ì'=>'i', 'í'=>'i', 'î'=>'i', 'ï'=>'i', 'ð'=>'o', 'ñ'=>'n',
  426.         'ò'=>'o', 'ó'=>'o', 'ô'=>'o', 'õ'=>'o', 'ö'=>'o', 'ő'=>'o', 'ø'=>'o', 'ù'=>'u', 'ú'=>'u', 'ű'=>'u',
  427.         'û'=>'u', 'ý'=>'y', 'ý'=>'y', 'þ'=>'b', 'ÿ'=>'y', 'Ŕ'=>'R', 'ŕ'=>'r', ' '=>'_', "'"=>'_', '/'=>''
  428.         );
  429.  
  430.         if (is_array($string)) {
  431.  
  432.           $cleaned = array();
  433.  
  434.           foreach ($string as $key => $clean) {
  435.             $clean = strtr($clean, $mapping);
  436.             $clean = preg_replace("/[^{$allow}_a-zA-Z0-9]/", '', $clean);
  437.             $cleaned[$key] = preg_replace('/[_]+/', '_', $clean); // remove double underscore
  438.           }
  439.         } else {
  440.           $string = strtr($string, $mapping);
  441.           $string = preg_replace("/[^{$allow}_a-zA-Z0-9]/", '', $string);
  442.           $cleaned = preg_replace('/[_]+/', '_', $string); // remove double underscore
  443.         }
  444.         return $cleaned;
  445.   }
  446.  
  447.   private function sanitize($var) {
  448.     $sanitized = strip_tags($var);
  449.     $sanitized = str_replace('http://', '', $sanitized);
  450.     $sanitized = str_replace('https://', '', $sanitized);
  451.     $sanitized = str_replace('../', '', $sanitized);
  452.     return $sanitized;
  453.   }
  454.  
  455.   private function checkFilename($path,$filename,$i='') {
  456.     if(!file_exists($path . $filename)) {
  457.       return $filename;
  458.     } else {
  459.       $_i = $i;
  460.       $tmp = explode(/*$this->config['upload']['suffix'] . */$i . '.',$filename);
  461.       if($i=='') {
  462.         $i=1;
  463.       } else {
  464.         $i++;
  465.       }
  466.       $filename = str_replace($_i . '.' . $tmp[(sizeof($tmp)-1)],$i . '.' . $tmp[(sizeof($tmp)-1)],$filename);
  467.       return $this->checkFilename($path,$filename,$i);
  468.     }
  469.   }
  470.  
  471.   private function loadLanguageFile() {
  472.  
  473.     // we load langCode var passed into URL if present and if exists
  474.     // else, we use default configuration var
  475.     $lang = $this->config['culture'];
  476.     if(isset($this->params['langCode']) && in_array($this->params['langCode'], $this->languages)) $lang = $this->params['langCode'];
  477.  
  478.     if(file_exists($this->root. 'scripts/languages/'.$lang.'.js')) {
  479.       $stream =file_get_contents($this->root. 'scripts/languages/'.$lang.'.js');
  480.       $this->language = json_decode($stream, true);
  481.     } else {
  482.       $stream =file_get_contents($this->root. 'scripts/languages/'.$lang.'.js');
  483.       $this->language = json_decode($stream, true);
  484.     }
  485.   }
  486.  
  487.   private function availableLanguages() {
  488.  
  489.     if ($handle = opendir($this->root.'/scripts/languages/')) {
  490.       while (false !== ($file = readdir($handle))) {
  491.         if ($file != "." && $file != "..") {
  492.           array_push($this->languages, pathinfo($file, PATHINFO_FILENAME));
  493.         }
  494.       }
  495.       closedir($handle);
  496.     }
  497.   }
  498. }
  499. ?>

Documentation generated on Thu, 03 May 2012 15:04:37 +0200 by phpDocumentor 1.4.1