<?php
/**
 * This file contains the PMO_MyLog class which implements logging facilities.
 *
 * This file is part of the PhpMyObject project,
 * an Object-Relational Mapping (ORM) system.
 * 
 * For questions, help, comments, discussion, etc., please join our
 * forum at {@link http://www.developpez.net/forums/forumdisplay.php?f=770} 
 *
 * PhpMyObject 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.
 *
 * This program is distributed in the hope that it 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 this program.  If not, see {@link http://www.gnu.org/licenses/}.
 *
 * @package			PhpMyObject
 * @subpackage 	PMO_Core
 * @author			Louis Lapointe <laplix@gmail.com>
 * @link				http://pmo.developpez.com/
 * @since			PhpMyObject v0.2.0
 * @version			$Revision$
 * @copyright		Copyright (C) 2008 Louis Lapointe
 * @copyright		Copyright (C) 2008 Louis Lapointe
 * @license			GPLv3 {@link http://www.gnu.org/licenses/gpl}
 * @filesource
 *
 */ 

/** requires the interface */
require_once(dirname(__FILE__).'/PMO_Log.php');

/**
 * This interface defines the methods a class must implement
 * to provide a working logger.
 * 
 * @package		PhpMyObject
 * @subpackage PMO_Core
 * @see			PMO_MyLog
 */ 
class PMO_MyLog implements PMO_Log {

	protected static $instance;

	protected $filename;

	protected $logging;

	protected $fp;

	private function __construct($filename = 'pmo.log') {
		$this->filename = $filename;
		$this->logging = false;
		$this->fp = null;
	}
	
	public function __destruct() {
		$this->destroy();
	}

	/**
	 * The implementation must create a PMO_MyLog object or if it already
	 * exists, return a reference to this object instance
	 *
	 * @param string $filename 	file name of the log. Defsaults to pmo.log
	 * @return PMO_Log
	 * @static
	 */
	static function factory($filename = 'pmo.log') {
		if (empty(self::$instance)) {
			self::$instance = new PMO_MyLog($filename);
		}
		return self::$instance;
	}

	public function destroy($killfile = false) {
		if (self::$instance) {
			$this->stop();
			$this->reset($killfile);
			self::$instance = NULL;
		}
	}

	/**
	 * Starts the logger.
	 */
	public function start() {
		$fname = '';
		if (!$this->logging) {
			$this->logging = true;
			if (!is_resource($this->fp)) {
				$this->fp = fopen($this->filename, 'a');
			}
		}
		$this->log('Logger started',3);
		return self::$instance;
	}
	
	/**
	 * Stops the log.
	 */
	public function stop() {
		$this->log('Logger stopped',4);
		$this->logging = false;
		if (is_resource($this->fp)) {
			fclose($this->fp);
			$this->fp = null;
		}
	}

	/**
	 * resets the log. If logging is on, starts anew.
	 */
	public function reset($killfile = true) {
		if (is_resource($this->fp)) {
			fclose($this->fp);
			$this->fp = null;
		}
		if ($killfile) {
			@unlink ($this->filename);
		}
		if ($this->logging) {
			$this->start();
		}
		return self::$instance;
	}

	/**
	 * Logs the incoming data.
	 *
	 * @param mixed $data 		Data to log
	 */
	public function log($data = null, $depth=2) {
		if ($this->logging) {
			$format = PMO_MyConfig::factory()->get('PMO_MyDbms.LOG_FORMAT');
			$output = date($format).' ' . $this->_caller($depth).' ==> '."\n". print_r($data,true)."\n";
			if (!is_resource($this->fp)) {
				$this->start();
			}
			fwrite($this->fp, $output);
		}
		return self::$instance;
	}

	public function getLog() {
		return file($this->filename);
	}

	private function _caller($depth) {
		$arr = debug_backtrace();
		$caller = 'Unknown';
		if (!empty($arr[$depth]['class'])) {
			$caller = $arr[$depth]['class'].'::'.$arr[$depth]['function'].'()::'.$arr[$depth-1]['line'];
			//$caller = print_r($arr[$depth],true);
		}
		if ($caller == 'Unknown') {
			$caller = print_r($arr,true);
		}
		return $caller;
	}
}
?>
