<?php
  class myUtility {
    static $log_dir = null;

    /**
     * Return extension of a file name
     *
     */
    public static function getFileExt($fileName) {
      $names = explode('.', $fileName);
      $i = count($names);
      if ($i>0) return  strtolower($names[$i-1]); else return '';
    }

    /**
     * return file name (no extension)
     *
     *
     * @param String $fileName
     */
    public static function getFileName($fileName) {
      $names = explode('.', $fileName);
      $i = count($names);
      if (count($names)>0) array_pop($names);
      return join('.', $names);
    }

    /**
     * return safe file name (lower byte character)
     *
     * @param unknown_type $fileName
     */
    public static function getSafeFileName($fileName) {
      $names = explode('.', $fileName);
      $ext = array_pop($names);
      $safe = preg_replace('@[^A-Za-z0-9_]+@', '', join($names));
      if ($safe=='') $safe = '0';
      return $safe.'.'.$ext;
    }

    /**
     * Convert from UTF-8 to non mark Vietnamese text
     *
     * @param String $value: input text
     * @return Non marke Vietnamese text
     */
    public static function vietDecode($value)
    {
      $vietChar 	= 'á|à|ả|ã|ạ|ă|ắ|ằ|ẳ|ẵ|ặ|â|ấ|ầ|ẩ|ẫ|ậ|é|è|ẻ|ẽ|ẹ|ê|ế|ề|ể|ễ|ệ|ó|ò|ỏ|õ|ọ|ơ|ớ|ờ|ở|ỡ|ợ|ô|ố|ồ|ổ|ỗ|ộ|ú|ù|ủ|ũ|ụ|ư|ứ|ừ|ử|ữ|ự|í|ì|ỉ|ĩ|ị|ý|ỳ|ỷ|ỹ|ỵ|đ|Á|À|Ả|Ã|Ạ|Ă|Ắ|Ằ|Ẳ|Ẵ|Ặ|Â|Ấ|Ầ|Ẩ|Ẫ|Ậ|É|È|Ẻ|Ẽ|Ẹ|Ê|Ế|Ề|Ể|Ễ|Ệ|Ó|Ò|Ỏ|Õ|Ọ|Ơ|Ớ|Ờ|Ở|Ỡ|Ợ|Ô|Ố|Ồ|Ổ|Ỗ|Ộ|Ú|Ù|Ủ|Ũ|Ụ|Ư|Ứ|Ừ|Ử|Ữ|Ự|Í|Ì|Ỉ|Ĩ|Ị|Ý|Ỳ|Ỷ|Ỹ|Ỵ|Đ';
			$engChar	= 'a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|e|e|e|e|e|e|e|e|e|e|e|o|o|o|o|o|o|o|o|o|o|o|o|o|o|o|o|o|u|u|u|u|u|u|u|u|u|u|u|i|i|i|i|i|y|y|y|y|y|d|A|A|A|A|A|A|A|A|A|A|A|A|A|A|A|A|A|E|E|E|E|E|E|E|E|E|E|E|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|U|U|U|U|U|U|U|U|U|U|U|I|I|I|I|I|Y|Y|Y|Y|Y|D';
			$arrVietChar 	= explode('|', $vietChar);
			$arrEngChar		= explode('|', $engChar);
			return str_replace($arrVietChar, $arrEngChar, $value);
    }

    public static function getUrlName($name) {
      $name = strtolower(myUtility::vietDecode($name));
      $name = preg_replace('@[^\w\d_]+@', '', $name);
      return $name;
    }

    /**
     * Check hard disk for not exist fileName, if file exists, change it name
     *
     * @param unknown_type $pathName
     * @param unknown_type $fileName
     * @param unknown_type $extName
     */
    public static function GetNoDuplicateFileName($pathName, &$fileName, $extName) {
      $i = 0;
      $newFileName = $fileName;
      while (file_exists("$pathName/$newFileName.$extName")) {
        $newFileName = $fileName . (++$i);
      }
      $fileName = $newFileName;
    }

    public static function moveDirectory($src, $dst) {
      if (!is_dir($dst)) {umask(0); mkdir($dst, 0777, true);}
      foreach (scandir($src) as $file) {
        if ($file=='.' || $file=='..') continue;
        $srcm = $src.'/'.$file;
        $dstm = $dst.'/'.$file;
        if (is_dir($srcm)) myUtility::moveDirectory($srcm, $dstm);
        else {
          rename($srcm, $dstm);
          chmod($dstm, 0777);
        }
      }
      rmdir($src);
    }

    public static function cleanDirectory($path) {
      foreach (scandir($path) as $dir) {
        if ($dir=='.' || $dir=='..') continue;
        $dname = $path.'/'.$dir; 
        if (is_dir($dname)) self::cleanDirectory($dname);
        else if (is_file($dname)) unlink($dname);
      }
      rmdir($path);
    }

    public static function ScaleAspect(&$width, &$height, $maxWidth, $maxHeight) {
      $sx = $maxWidth / $width;
      $sy = $maxHeight / $height;
      if ($sx>$sy) $sx = $sy;
      $width = round($width * $sx / 2) * 2;
      $height = round($height * $sx / 2) * 2;
    }

    /**
     * Enter description here...
     *
     * @param unknown_type $fileName
     * @param unknown_type $fileThumb
     * @param unknown_type $time
     * @param unknown_type $info
     * @return unknown
     */
    public static function FlvToThumbnail($fileName, $fileThumb, $time = null, $info = null) {
      try {
        if ($info==null) $info = self::GetVideoInfo($fileName);

        if (!isset($info['ID_VIDEO_FORMAT'])) return false;
        if (!isset($info['ID_LENGTH'])) return false;
        $width = doubleval($info['ID_VIDEO_WIDTH']);
        $height = doubleval($info['ID_VIDEO_HEIGHT']);

        self::ScaleAspect($width, $height, 150, 100);

        if ($time===null) $time = doubleval($info['ID_LENGTH']) / 2;

        $logFileName = 'convert_flv_thumb.log';

        // no .THM file so need to use ffmpeg to get tumbnail image
    		//ffmpeg -y -i MVI_6640.AVI -s qcif -f mjpeg -t 0.001 movie.jpg
    		$ffmpeg_cmd = sfConfig::get('app_ffmpeg_exe');
    		$command = "$ffmpeg_cmd -y -v 0 -itsoffset -$time -i ". escapeshellarg($fileName) ." -s {$width}x{$height} -f mjpeg -vframes 1 ". escapeshellarg($fileThumb);
    		//myUtility::log("\n\n\n********".$command, $logFileName);

    		$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("pipe", "w"),  // stdout is a pipe that the child will write to
        );
        $process = proc_open($command, $descriptorspec, $pipes);
        if (is_resource($process)) {
          $ret = true;
          while (!feof($pipes[2])) {
            $line = fgets($pipes[2],1024);
            //myUtility::log($line, $logFileName);
            if (preg_match('@: no such file or directory@', $line)) $ret = false;
            if (preg_match('@^Error while opening codec for output stream@', $line)) $ret = false;
            if (preg_match('@Unknown format@', $line)) $ret = false;
          }
          fclose($pipes[2]);
          proc_close($process);
          return $ret;
        } else return false;
      } catch (Exception $e) {
        myUtility::log($e->getMessage(), $logFileName);
        return false;
      }
    }

    public static function ImageToJpg($imageName, $jpgName) {
      $convert_cmd = sfConfig::get('app_convert_exe');
      $command = "$convert_cmd ". escapeshellarg($imageName) ." ". escapeshellarg($jpgName);
      $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
      );
      $process = proc_open($command, $descriptorspec, $pipes);
      if (is_resource($process)) {
        while (!feof($pipes[1])) {
          $line = fgets($pipes[1], 1024);
        }
        fclose($pipes[1]);
        proc_close($process);
      }
    }

    public static function MovieToFlv($movieName, $flvName) {
      try {
        $logFileName = 'convert_flv.log';
        $ffmpeg_cmd = sfConfig::get('app_ffmpeg_exe');

    		// generate the Flash FLV version of the file
      	// cif = 352x288
      	$command = "$ffmpeg_cmd -y -v 0 -i ". escapeshellarg($movieName) ." -s cif -ar 44100 -r 15 ". escapeshellarg($flvName);
      	//myUtility::log("\n\n\n********".$command, $logFileName);

      	$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("pipe", "w"),  // stdout is a pipe that the child will write to
        );
      	$process = proc_open($command, $descriptorspec, $pipes);
        if (is_resource($process)) {
          $ret = true;
          while (!feof($pipes[2])) {
            $line = fgets($pipes[2],1024);
            //myUtility::log($line, $logFileName);
            if (preg_match('@: no such file or directory@', $line)) $ret = false;
            if (preg_match('@^Error while opening codec for output stream@', $line)) $ret = false;
            if (preg_match('@Unknown format@', $line)) $ret = false;
          }
          fclose($pipes[2]);
          proc_close($process);
          return $ret;
        } else return false;
      } catch (Exception $e) {
        myUtility::log($e->getMessage(), $logFileName);
        return false;
      }
    }

    /**
     * Get Video info
     *
     * @param unknown_type $movieName
     * @return array of info
     *   'ID_VIDEO_WIDTH' => width of video
     *   'ID_VIDEO_HEIGHT' => height of video
     *   'ID_LENGTH' => lengh of video (in second)
     *   'ID_VIDEO_FORMAT' => video codec
     *   'ID_AUDIO_FORMAT' => audio codec
     */
    public static function GetVideoInfo($movieName) {
      try {
        $logFileName = 'video_info.log';
        $mplayer_cmd = sfConfig::get('app_mplayer_exe');

    		// generate the Flash FLV version of the file
      	// cif = 352x288
      	$command = "$mplayer_cmd -identify " . escapeshellarg($movieName) ." -ao null -vo null -frames 0";
      	//myUtility::log("\n\n\n********".$command, $logFileName);

      	$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("pipe", "w"),  // stdout is a pipe that the child will write to
        );
      	$process = proc_open($command, $descriptorspec, $pipes);
        if (is_resource($process)) {
          $ret = array();
          while (!feof($pipes[1])) {
            $line = fgets($pipes[1],1024);
            //myUtility::log($line, $logFileName);
            if (preg_match('@ID_VIDEO_FORMAT|ID_VIDEO_WIDTH|ID_VIDEO_HEIGHT|ID_AUDIO_FORMAT|ID_LENGTH@', $line)) {
              $col = explode('=', trim($line));
              $ret[$col[0]] = $col[1];
            }
          }
          fclose($pipes[1]);
          proc_close($process);
          return $ret;
        } else return false;
      } catch (Exception $e) {
        myUtility::log($e->getMessage(), $logFileName);
        return array();
      }
    }

    public static function SizeImage($maxWidth, $maxHW, $fileName, $thumbFileName, $allowBigger=true, $externalFileName=false) {
      try {
        $logFileName = 'convert_img.log';

        $width = intval($maxWidth); $height = intval($maxHW);
        if ($width==null || $height==null) return false;
        if (false==$allowBigger) {
          list($mwidth, $mheight) = myUtility::getImageSize($fileName, $externalFileName);
          if ($mwidth==0 || $mheight==0) return  false;
          $mwidth = intval($mwidth); $mheight = intval($mheight);
          if ($mwidth<=$width && $mheight<=$height) {
            $width = $mwidth;
            $height = $mheight;
          }
        }

        $img_cmd = sfConfig::get('app_convert_exe');
        if ($externalFileName)
          $fileName = '"'.$fileName.'"';
        else
          $fileName = escapeshellarg($fileName);
      	$command = "$img_cmd -resize {$width}x{$height} -flatten -background white -verbose " . $fileName . ' ' . escapeshellarg($thumbFileName);
      	//myUtility::log("Execute ".$command, $logFileName, "\n");

      	$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
        );
      	$process = proc_open($command, $descriptorspec, $pipes);

      	if (is_resource($process)) {
      	  $ret = true;
      	  while (!feof($pipes[1])) {
            $line = fgets($pipes[1],1024);
            //if ($line != '') myUtility::log($line, $logFileName);
            if (preg_match('@missing an image filename@', $line)) $ret = false;
          }
          fclose($pipes[1]);
      	  proc_close($process);
      	  return $ret;
      	}
      	return false;
      } catch (Exception $e) {
        myUtility::log($e->getMessage(), $logFileName);
        return false;
      }
    }

    public static function FlvAddMeta($fileName) {
      try {
        $logFileName = 'meta_flv.log';
        $img_cmd = sfConfig::get('app_flvtool2_exe');

        $command = "$img_cmd -U " . escapeshellarg($fileName);
        $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
        );
        //myUtility::log($command, $logFileName);
        $process = proc_open($command, $descriptorspec, $pipes);

        if (is_resource($process)) {
          $ret = true;
          while (!feof($pipes[1])) {
            //myUtility::log($line, $logFileName);
            $line = fgets($pipes[1],1024);
          }
          fclose($pipes[1]);
          proc_close($process);
          return $ret;
        } else return false;
      } catch (Exception $e) {
        myUtility::log($e->getMessage(), $logFileName);
        return false;
      }
    }

    public static function getSWFImageSize($fileName) {
      try {
        $width = 640;
        $height = 480;

        $img_cmd =sfConfig::get('app_swfdump_exe');
        $command = "$img_cmd -X -Y " . escapeshellarg($fileName);
        $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
        );
        $process = proc_open($command, $descriptorspec, $pipes);

        if (is_resource($process)) {
          while (!feof($pipes[1])) {
            $line = fgets($pipes[1],1024);
            if (preg_match('@-X ([0-9]+) -Y ([0-9]+)@', $line, $size)) {
              $width = intval($size[1]);
              $height = intval($size[2]);
            }
          }
          fclose($pipes[1]);
          proc_close($process);
        }
        return array($width, $height);
      } catch (Exception $e) {
        return array($width, $height);
      }
    }

    public static function getImageSize($fileName, $externalFile=false) {

      $length = strlen($fileName);
      $ext = $length>3?substr($fileName, $length-3, 3):'';
      $ext = strtolower($ext);
      if ($ext=='swf') return self::getSWFImageSize($fileName);
      $width = 0;
      $height = 0;

      if ($externalFile)
        $fileName = '"'.$fileName.'"';
      else
        $fileName = escapeshellarg($fileName);

      $img_cmd = sfConfig::get('app_identify_exe');
      $command = "$img_cmd -format %wx%h\\n " . $fileName;
      $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
      );
      $process = proc_open($command, $descriptorspec, $pipes);

      if (is_resource($process)) {
        $ret = true;
        while (!feof($pipes[1])) {
          $line = trim(fgets($pipes[1],1024));
          if (preg_match('@Improper image header@', $line)) $ret = false;
          if (preg_match('@Not a JPEG file@', $line)) $ret = false;
          if (preg_match('@no decode delegate for this image format@', $line)) $ret = false;
          if ($line!=null) {
            if ($width == null && preg_match('@([0-9]+)x([0-9]+)@', $line, $size)) {
              $width = intval($size[1]);
              $height = intval($size[2]);
            }
          }
        }
        fclose($pipes[1]);
        proc_close($process);
      } else $ret = false;
      return array($width, $height);
    }

    public static function global_image_tag($fileName, $width, $height, $vars = null) {
      $ext = myUtility::getFileExt($fileName);
      switch ($ext) {
        case 'swf':
          return flash_tag($fileName, $width, $height, $vars, true);
        default:
          return image_tag($fileName, array('width'=>$width, 'height'=>$height));
      }
    }

    public static function redirectWithCustomReferer($host, $retHost='', $param = null) {
      echo "
            <head>
              <meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
            </head>
            <form method='post' action='$host'>
              <input type='hidden' id='ret' name='ret' value='$retHost'/>
            </form>
            Xin quý vị đợi giây lát... Nếu trang web không tự động chuyển, hãy <a href='#' onclick='submitform()'>Click vào đây</a>
            <script>
              function submitform() {
                document.forms[0].submit();
              }
              window.setTimeout('submitform()',50);
            </script>
           ";
      exit();
    }

    /**
     * execute native sql
     *
     * @param unknown_type $sql
     * @return array of rows, each row is an array of fields (no key)
     */
    public static function execSql($sql, $noResult = false) {
      $criteria = new Criteria();
      $dbMap = Propel::getDatabaseMap($criteria->getDbName());
      $db = Propel::getDB($criteria->getDbName());

      $con = Propel::getConnection($criteria->getDbName(), Propel::CONNECTION_READ);

      $stmt = $con->prepare($sql);
      $stmt->execute();
      if ($noResult==true) return;
      $rows = array();
      try {
        while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
          $rows[] = $row;
        }
      } catch (Exception $e) {}
      $stmt->closeCursor();
      return $rows;
    }

    public static function log($message, $fileName = 'blog.log', $prefix = '') {
      if (null == self::$log_dir) self::$log_dir = sfConfig::get('sf_log_dir');
      error_log($prefix.date('Y-m-d H:i:s ').substr(session_id(), 0, 5).' '.$message."\n", 3, self::$log_dir.'/'.$fileName);
    }

    public static function track_upload($message, $logFile) {
      error_log(date('H:i:s ').$message."\n", 3, sfConfig::get('sf_web_dir').'/uploads/previews/upinfo/'.$logFile.'_'.date('Ymd').'.log');
    }

    /**
     * Truncates +text+ to the length of +length+ and replaces the last three characters with the +truncate_string+
     * if the +text+ is longer than +length+.
     */
    public static function mb_truncate_text($text, $length = 33, $truncate_string = '...', $truncate_lastspace = false)
    {
      if ($text == '') {
        return '';
      }

      if (mb_strlen($text, 'utf8') > $length) {
        $truncate_text = mb_substr($text, 0, $length - strlen($truncate_string), 'utf8');
        if ($truncate_lastspace) {
          $truncate_text = preg_replace('/\s+?(\S+)?$/', '', $truncate_text);
        }

        return $truncate_text.$truncate_string;
      }
      else {
        return $text;
      }
    }

    public static function htmlToText($str) {
      $text = new html2text($str);
      return $text->get_text();
    }

    /**
     * Return first day of week that include $date
     *
     * @param string $date (not include time)
     * @return string first day of week
     */
    public static function dateToWeek($date) {
      $time = strtotime($date);
      $dayOfWeek = date('w', $time);
      return date('Y-m-d', strtotime("$date -$dayOfWeek day"));
    }

    /**
     * Create random password
     *
     * @param int $lenght: length of random password
     * @return password
     */
    public function create_password($length = 6)
    {
      $chars = '0123456789';
      srand(time());
      $pass = '';
      for ($i = 0; $i < $length; $i++) {
        $num = rand(0, strlen($chars)-1);
        $pass .= $chars[$num];
      }
      return $pass;
    }

    public function getRealIpAddr() {
      if (!empty($_SERVER['HTTP_CLIENT_IP'])) {   //check ip from share internet
        $ip = $_SERVER['HTTP_CLIENT_IP'];
      } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {  //to check ip is pass from proxy
        $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
      } else {
        $ip = $_SERVER['REMOTE_ADDR'];
      }
      return $ip;
    }

    public function validate($filterclass, &$data, &$error) {
      $filter = new $filterclass();
      $filter->initialize(null);
      return $filter->execute($data, $error);
    }
  }
?>
