<?php
/*
Officity - Web application platform - Version 6.0 - 2011-07-05

François Dispaux, Boris Verdeyen, Thomas Hermant,
Jérémie Roy, Grégory Meurice, Abdelila Harbi, 
Marc Mignonsin, Jonathan Sanchez, Julien Gonzalez, Pierre Fouchez

Sushee and Officity is © Copyright 2011 Nectil SA.

`/sushee-source/sushee/Library/updates/20101025-logs/portLogs.class.php` is part of Officity.

Sushee is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Officity and Sushee are distributed in the hope that they will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Sushee. If not, see <http://www.gnu.org/licenses/>.
*/
include_once('../../../common/log.class.php');
include_once('../../../common/date.class.php');

define('PORT_TIME_LIMIT',50);

class Sushee_Logports_iterator{
	
	var $last_month = false;
	
	function Sushee_Logports_iterator($last_month=false){
		$this->last_month = $last_month;
	}
	
	function initialize(){
		$db_conn = db_connect();
		$sql = 'SELECT `Path` FROM `sushee:logsport` ';
		if($this->last_month){
			$date = new Date();
			$date->addMonth(-1);
			$prefix = $date->getYear().'-'.$date->getMonth();
			$sql.=' WHERE `Path` LIKE "/logs/'.encode_for_db($prefix).'%"';
		}else{
			$prefix = date('Y-m');
		}
		$sql.=' LIMIT 0,1';
		sql_log($sql);
		$row = $db_conn->getRow($sql);
		if($row){
			// table and data already exist
		}else{
			$sql = 'CREATE TABLE `sushee:logsport` (
			`Path` VARCHAR( 255 ) NOT NULL ,
			`Ported` TINYINT( 1 ) NOT NULL ,
			`Offset` INT NOT NULL,
			PRIMARY KEY (`Path`)
			) ENGINE = MYISAM ;';
			$db_conn->execute($sql);
			
			// looping through the log folder
			$folder = new UserActionLogFolder();
			
			while($file = $folder->next()){
				// if porting the last month, we include the logs prefixed with the last month date, if not, we exclude them
				if( (!$this->last_month && substr($file->getName(),0,7)!=$prefix) || ($this->last_month && substr($file->getName(),0,7)==$prefix)){
					$sql = 'INSERT INTO `sushee:logsport`(`Path`) VALUES("'.encode_for_db($file->getPath()).'");';
					$db_conn->execute($sql);
				}
			}
		}
		
		
	}
	
	function next(){
		$sql = 'SELECT * FROM `sushee:logsport` WHERE `Ported` = 0';
		$db_conn = db_connect();
		$row = $db_conn->getRow($sql);
		if($row){
			return new Sushee_Logport($row);
		}
		return false;
	}
	
}

class Sushee_Logport{
	
	var $path = false;
	var $row = false;
	
	function Sushee_Logport($path){
		if(is_array($path)){
			$this->row = $path;
			$this->path = $this->row['Path'];
		}else{
			$this->path = $path;
		}
	}
	
	function getPath(){
		return $this->path;
	}
	
	function isPorted(){
		$row = $this->getRow();
		if($row){
			return $row['Ported'];
		}else
			return false;
	}
	
	
	
	function getOffset(){
		$row = $this->getRow();
		if($row){
			return $row['Offset'];
		}else
			return 0;
	}
	
	function getRow(){
		if(!$this->row){
			$sql = 'SELECT * FROM `sushee:logsport` WHERE Path = "'.encode_for_db($this->path).'" LIMIT 0,1';
			$db_conn = db_connect();
			$this->row = $db_conn->getRow($sql);
		}
		return $this->row;
	}
	
	function saveOffset($offset){
		$db_conn = db_connect();
		$sql = 'REPLACE `sushee:logsport`(`Path`,`Offset`) VALUES ("'.encode_for_db($this->path).'","'.encode_for_db($offset).'")';
		$db_conn->execute($sql);
	}
	
	function markAsPorted(){
		$db_conn = db_connect();
		$sql = 'REPLACE `sushee:logsport`(`Path`,`Ported`) VALUES ("'.encode_for_db($this->path).'",1)';
		$db_conn->execute($sql);
	}
	
}

class Sushee_LogFilePorter{
	
	var $log_inserter = false;
	var $start_line = 0;
	var $compress = true;
	
	function Sushee_LogFilePorter($log_inserter){
		$this->log_inserter = $log_inserter;
	}
	
	function setStartOffset($offset){
		$this->start_offset = $offset;
	}
	
	function enableCompression($boolean=true){
		$this->compress = $boolean;
	}
	
	function execute($logport){
		global $directoryRoot;
		$i = 0;
		// we have in the database the trace of which files are already ported and until which line
		$file = new Sushee_GZippedLogFile($logport->getPath());
		// reading every line of the file
		$file->_openForRead();
		// going to the offset marked in the database
		$current_offset = $logport->getOffset();
		$file->goToOffset($current_offset);
		
		while($line = $file->getNextLine()){
			//echo encode_to_xml(implode('///',$line)).'<br/>';
			// looking which module and which object is concerned
			$action = new UserActionLog();
			// taking the csv line and giving it to parse
			$action->parse($line);
			$object = $action->getObject();
			if($object){
				$type = $object->getType();
				$ID = $object->getID();
				if($type && $ID){
					//---------------------------
					// logging in module logfile
					//---------------------------
					// determining the path of the file
					$directory = '/logs/modules/'.$type.'/';
					makedir($directoryRoot.$directory);
					$path = $directory;
					$date = $action->getDate();
					$path.=$date->getYear().'-'.$date->getMonth().'.log';
					if($this->compress){
						$path.='.gz';
					}

					// inserting in file
					$logfile = new Sushee_GZippedLogFile($path);
					$this->log_inserter->execute($logfile,$action);

					//---------------------------
					// logging in element logfile
					//---------------------------
					// determining the path of the file
					$directory = '/logs/elements/'.$type.'/';
					$low_limit = (int)(floor($ID / EA_PAGINATE)) * EA_PAGINATE;
					$high_limit = $low_limit + EA_PAGINATE;
					$directory.=$low_limit.'-'.$high_limit.'/';
					makedir($directoryRoot.$directory);
					$path = $directory;
					$path.=$ID.'.log';
					if($this->compress){
						$path.='.gz';
					}

					// inserting in file
					$logfile = new Sushee_GZippedLogFile($path);
					$this->log_inserter->execute($logfile,$action);
				}
				
			}
			
			
			$i++;
			if(getTimer() > PORT_TIME_LIMIT )
				break;
			// end loop
		}
		if(!$line){ // we have finished every line
			$logport->markAsPorted();
		}else{ // we have not finished, we save where we arrived in database
			$logport->saveOffset($file->getOffset());
		}
		//echo(getTimer().' for '.$i.' lines of '.$file->getPath().'<br/>');
	}
	
}

// inserts a line in a logfile, at the end
class Sushee_LogBasicInserter{
	
	function Sushee_LogBasicInserter(){
	}
	
	function execute($logfile,$log){
		// just append log in the file
		$logfile->append($log->toString());
	}
	
}

// inserts a line in a logfile, but looping through each line to insert the new line at the right position (sorted by date)
class Sushee_LogSortedInserter{
	
	function Sushee_LogSortedInserter(){
	}
	
	function execute($logfile,$log){
		$logfile->_openForRead();
		// looping on everyline of logfile
		$logfile->lock(); // locking to be sure nothing is inserted in the meantime, because we will rewrite the whole file on the disk
		$date = $log->getDate();
		$before = ''; // lines before the line we are trying to add
		$after = ''; // lines after the line we are trying to add
		$i = 0;
		while($line = $logfile->getNextLine()){
			// looking if date is bigger or smaller than the date of the current action
			$line_log = new UserActionLog();
			// taking the csv line and giving it to parse
			$line_log->parse($line);
			$line_date = $line_log->getDate();
			// if its lower, go on, if its bigger stop
			if($date->isGreaterThan($line_date)){
				// line is going to be inserted before this one
				$before.=$line_log->toString();
			}else{
				// line is going to be inserted after this one
				$after.=$line_log->toString();
			}
			$i++;
		}
		$logfile->unlock();
		$logfile->close();
		$logfile->_openForWrite();
		$logfile->lock();
		$logfile->save($before.$log->toString().$after);
		$logfile->unlock();
		$logfile->close();
		//die('saving '.($i+1).' lines in '.$logfile->getPath().'<br/>');
		// release file
		
		// end loop
	}
}


?>