<?php

class PHP_FTP {
	var $server = '';
	var $username = '';
	var $password = '';
	var $port = 21;
	var $conn = null;
	var $logfile = "/data/logs/ftp.log";

	function __construct($server, $username='anonymous', $password='e@mail.com', $port=21) {
		$this->server = $server;
		$this->username = $username;
		$this->password = $password;
		$this->port = $port;
		$this->open_connection();
	}
	
	function __destruct() {
		$this->close_connection();
	}

	function open_connection($passive=TRUE) {
		for ($i = 0; $i <= 4; $i++) {
			if ($this->conn = ftp_connect($this->server, $this->port)) break;
			if ($i == 4) die("Could not connect to FTP\n");
			sleep(3);
		}
		ftp_login($this->conn, $this->username, $this->password) or die("Could not login to FTP\n");
		ftp_pasv($this->conn, $passive);
		return $this->conn;
	}

	function close_connection() {
		if ($this->conn) ftp_close($this->conn);
		$this->conn = null;
	}
	
	function size($filename) {
		return ftp_size($this->conn, $filename);
	}

	function logToFile($msg) {
		$fd = fopen($this->logfile, "a");
		fwrite($fd, "[".date('Y-m-d h:i:s')."] ".$msg."\n");
		fclose($fd);
	}

	function get($filename, $save_as) {
		echo "Downloading $filename\n";
		for ($i = 0; $i <= 2; $i++) {
			if (ftp_get($this->conn, $save_as, $filename, FTP_BINARY)) {
				if ($i > 0) $this->logToFile("Downloaded $filename after $i reconnection");
				break;
			}
			if ($i == 2) $this->logToFile("Error download $filename");
			$this->close_connection();
			$this->open_connection();
		}
		return ($i <= 2);
	}

	function dget($dir_name_server, $dir_name_local, $subd=FALSE, $ignore_dir=NULL, $show_dir=FALSE) {
		//get file list for directory to be downloaded
		for ($i = 0; $i <= 4; $i++) {
			$ls_dir = ftp_rawlist($this->conn, $dir_name_server);
			if (is_array($ls_dir)) {
				if ($i > 0) $this->logtoFile("Get list of $dir_name_server after $i reconnection");
				break;
			}
			if ($i == 4) $this->logtoFile("Error get list of $dir_name_server");
			$this->close_connection();
			$this->open_connection();
		}
		if ($i > 4) return array(0, 0);  //could not get file list after 4 times retrying
		if (sizeof($ls_dir) == 0) return array(0, 0);  //no file in the directory

		$numFile = 0;
		$numCopy = 0;
		$firstCreate = false;
		//download all files in the current directory, recursively call dget() to download sub-directories
		for ($i = 0; $i < sizeof($ls_dir); $i++) {
			$info = preg_split("/[\s]+/", $ls_dir[$i], 9);
			if (sizeof($info) < 9) {$this->logToFile("Info invalid: $ls_dir[$i]"); continue;}
			$f_name = $info[8];
			$path = $dir_name_local."/".$f_name;
			$percent = round(($i+1)/sizeof($ls_dir)*100);
			
			if ($ls_dir[$i][0] == 'd') {
				if (!$subd || $ignore_dir && in_array($f_name, $ignore_dir)) continue;
				if ($show_dir) echo date('h:i:s')."($percent%) seek directory: $dir_name_server/$f_name\n";
				list($nf, $nc) = $this->dget($dir_name_server."/".$f_name, $path, $subd, $ignore_dir);
				$numFile += $nf;
				$numCopy += $nc;
			} else {
				$numFile++;
				if (file_exists($path) && filesize($path)==$info[4]) continue;
				//create local directory
				if (!$firstCreate && !file_exists($dir_name_local)) {
					$new_dir = mkdir($dir_name_local, 0777, true);
					$firstCreate = true;
				}
				$this->get($dir_name_server."/".$f_name, $path);
				$numCopy++;
			}
		}
		return array($numFile, $numCopy);
	}
}
