<?php

class myFolder {
  public $fileList = array();
  public $dirList = array();

  public function addFile($fileName, $fullFileName) {
    $this->fileList[$fileName] = $fullFileName;
  }

  public function addFolder($dirName) {
    $this->dirList[$dirName] = new myFolder();
  }

  public function &getFolder($dirName, &$folderList) {
    $temp = @$this->dirList[$dirName];
    if ($temp==null) {
      $this->addFolder($dirName);
      $folderList[] = $dirName;
    }

    return $this->dirList[$dirName];
  }
};

class myListFile
{
  public $listFile;
  public $listFileName = array();
  public $listFileNameArray = array();
  public $listFolder = array();
  public $listFileSizeArray = array();
  public $listFileSize = array();


  public function myListFile() {
    $this->listFile = new myFolder();
  }

  public function addFile($path, $att, $size = 0)
  {
    $path = str_replace("\\", '/', $path);
    $pathArr = split('/', $path);
    $fileName = '';
    if ($att[0]!='D') $fileName = array_pop($pathArr);
    $pathObj = &$this->listFile;
    for ($i=0; $i<count($pathArr); $i++)
      $pathObj = &$pathObj->getFolder($pathArr[$i], $this->listFolder);

    if ($fileName!=null) {
      $pathObj->addFile($fileName, $path);
      $this->listFileName[$fileName] = $path;
      $this->listFileNameArray[] = $path;
      $this->listFileSizeArray[] = $size;
      $this->listFileSize[$path] = $size;
    }
  }

  public function isPPT(&$fileName) {
    if (count($this->listFileName)==1) {
      foreach ($this->listFileName as $fileName) {
        return myUtility::getFileExt($fileName  ) == 'ppt';
      }
    }
    return false;
  }

  public function cmpdirlevel($a, $b) {
    return count(explode('/', $a)) > count(explode('/', $b));
  }

  public function findFirstFile($info)
  {
    if (!is_array($info)) $info = array($info);
    $listFileNameArray = $this->listFileNameArray;
    usort($listFileNameArray, array(__CLASS__, 'cmpdirlevel'));

    $result = array();
    foreach ($listFileNameArray as $file) {
      $ext = pathinfo($file, PATHINFO_EXTENSION);
      $name = pathinfo($file, PATHINFO_BASENAME);
      if (in_array($ext, $info) && !isset($result[$ext])) $result[$ext] = $file;
      if (in_array($name, $info) && !isset($result[$name])) $result[$name] = $file;
    }
    foreach ($info as $name) {
      if (isset($result[$name])) return $result[$name];
    }
    return '';
  }

  public function findFile($extension, &$findSize)
  {
    if (!is_array($extension)) $extension = array($extension);
    $ret = array();
    $findSize = array();
    $n = count($this->listFileNameArray);
    for ($i = 0; $i < $n; $i++) {
      $file = $this->listFileNameArray[$i];
      if (in_array(myUtility::getFileExt($file), $extension)) {
        $ret[] = $file;
        $findSize[] = $this->listFileSizeArray[$i];
      }
    }
    return $ret;
  }

  public function pregFindFile($pattern, &$findSize) {
    $ret = array();
    $findSize = array();
    $n = count($this->listFileNameArray);
    for ($i = 0; $i < $n; $i++) {
      $file = $this->listFileNameArray[$i];
      if (preg_match($pattern, $file)) {
        $ret[] = $file;
        $findSize[] = $this->listFileSizeArray[$i];
      }
    }
    return $ret;
  }
};

class myZip {
  public static function Unzip($zipFile, $destFolder)
  {
    $zip_cmd = sfConfig::get('app_7z_exe');
  	$command = "$zip_cmd x -y -p123456 -o" . escapeshellarg($destFolder) . ' ' . escapeshellarg($zipFile);
  	$descriptorspec = array(
       0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
       1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
       //2 => array("file", "/tmp/error-output.txt", "a") // stderr is a file to write to
    );
    //var_dump($command); exit();
  	$process = proc_open($command, $descriptorspec, $pipes);

  	if (is_resource($process)) {
  	  while (!feof($pipes[1])) {
        $line = fgets($pipes[1],1024);
        if (preg_match('@Wrong password@', $line)) {
          fclose($pipes[1]);
          proc_close($process);
          return false;
        }
      }
      fclose($pipes[1]);
  	  proc_close($process);
  	}
  }

  /**
   * Enter description here...
   *
   * @param string $zipFile
   * @return myListFile
   */
  public static function ListFile($zipFile)
  {
    //$logFileName = 'zip.log';
    $listFile = new myListFile();
    $ext = myUtility::getFileExt($zipFile);
    if ($ext!='zip' && $ext!='7z' && $ext!='rar' && $ext!='gzip' && $ext!='gz') {
      $zipFile = str_replace("\\", '/', $zipFile);
      $zipArray = split('/', $zipFile);
      $zipFile = array_pop($zipArray);
      $listFile->addFile($zipFile, '.', 0);
      return $listFile;
    }

    $zip_cmd = sfConfig::get('app_7z_exe');
    $descriptorspec = array(
       0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
       1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
    );

    ///////////////////////////////////////////////////////////////////////
    // Check password
    $command = "$zip_cmd l -slt -p123456 " . escapeshellarg($zipFile);
    //myUtility::log("\n\n\n\n$command", $logFileName);
  	$process = proc_open($command, $descriptorspec, $pipes);
  	if (is_resource($process)) {
  	  while (!feof($pipes[1])) {
 	      $s = fgets($pipes[1], 1024);
 	      //myUtility::log($s, $logFileName);
        if (preg_match('@Wrong password|not supported archive|Encrypted = \+@', $s)) {
          fclose($pipes[1]);
          proc_close($process);
          return $listFile;
        }
  	  }
      fclose($pipes[1]);
  	  proc_close($process);
  	} else return $listFile;

  	///////////////////////////////////////////////////////////////////////
  	// Lay danh sach ten file
    $command = "$zip_cmd l -p123456 " . escapeshellarg($zipFile);
    //myUtility::log("\n\n\n\n$command", $logFileName);
  	$process = proc_open($command, $descriptorspec, $pipes);

  	if (is_resource($process)) {
  	  while (!feof($pipes[1])) {
        $s = fgets($pipes[1], 1024);
        //myUtility::log($s, $logFileName);
        if (preg_match('@Wrong password@', $s)) {
          fclose($pipes[1]);
          proc_close($process);
          return $listFile;
        }
        if (preg_match('@[0-9]+\-[0-9]+\-[0-9]+ [0-9]+:[0-9]+:[0-9]+ (.....) +([0-9]+) +([0-9]+)?  (.*)$@', $s, $match)) {
          $match[3] = preg_replace('@\r|\n@', '', $match[3]);
          $listFile->addFile($match[4], $match[1], $match[2]);
        }
  	  }
      fclose($pipes[1]);
  	  proc_close($process);
  	  return $listFile;
  	} else return $listFile;
  }
};
