Login   Register  
PHP Classes
elePHPant
Icontem

File: Debug.php

Recommend this page to a friend!
Stumble It! Stumble It! Bookmark in del.icio.us Bookmark in del.icio.us
  Classes of Artur Barseghyan  >  DebugLive  >  Debug.php  >  Download  
File: Debug.php
Role: Class source
Content type: text/plain
Description: Debug class
Class: DebugLive
Show script debug information to authorized users
Author: By
Last change: Some updates.
Date: 5 years ago
Size: 16,698 bytes
 

Contents

Class file image Download
<?php
/**
 * Debug sites live.
 * @example See file "debug_example.php" for usage examples
 * @author Artur Barseghyan www@foreverchild.info
 * @version 0.2
 * @copyright Artur Barseghyan
 * @license GPL 
 */
class Debug {
	/**
	 * Boolean. Default value of the <$_UseBuffer> flag.
	 */
	const USE_BUFFER = false;


	/**
	 * Boolean. Default value of the <$_DisplayNone> flag.
	 */
	const DISPLAY_NONE = true;


	/**
	 * Boolean. Default value of <$_DisplayFullTrace> flag.
	 */
	const DISPLAY_FULL_TRACE = false;


	/**
	 * Boolean. Default value for <$_AddDebugInfo> flag.
	 */
	const ADD_DEBUG_INFO = true;


	/**
	 * String. Default value for <$_DumpFunction> value.
	 */
	const DUMP_FUNCTION = 'print_r';


	/**
	 * String.
	 */
	const ACCESS_CHECK_IP = 'ip';


	/**
	 * String.
	 */
	const ACCESS_CHECK_FINGERPRINT = 'fingerprint';


	/**
	 * String.
	 */
	const FINGERPRINT_PREFIX = 'lgdl*4399@FJ-00%dasdsa^';


	/**
	 * Holds an instance of Debug object.
	 *
	 * @var Debug object
	 */
	private static $_Instance;


	/**
	 * Enable debugging flag.
	 *
	 * @var Bool
	 */
	private $_enable;


	/**
	 * Access control parameters.
	 * @var Associative Array of Strings
	 */
	private $_accessParams;


    private $_errorLog = array();


	/**
	 * Access control IPs
	 *
	 * @var Array of Associative Arrays of Strings
	 */
	private $_ips = array();


	/**
	 * If set to true, debug info will be added.
	 *
	 * @var Bool
	 */
	private $_addDebugInfo = self::ADD_DEBUG_INFO;


	/**
	 * If set to true, output will be included in the scope of &gl;div&gt; tags
	 * with CSS property set to display:none;
	 * 
	 * @var Bool
	 */
	private $_displayNone = self::DISPLAY_NONE;


	/**
	 * If set to true, full debug trace will be added.
	 *
	 * @var Bool
	 */
	private $_displayFullTrace = self::DISPLAY_FULL_TRACE;


	/**
	 * If set to true, debug info will be buffered instead of direct output.
	 *
	 * @var Bool
	 */
	private $_useBuffer = self::USE_BUFFER;


	/**
	 * Dump function to use.
	 *
	 * @var String
	 */
	private $_dumpFunction = self::DUMP_FUNCTION;


	/**
	 * List of allowed dump functions.
	 *
	 * @var Array
	 */
	private $_dumpFunctions = array(	'print_r' => 'print_r',
											'var_dump' => 'var_dump');


	/**
	 * Buffer data.
	 *
	 * @var Array of Strings
	 */
	private $_bufferData = array();


	/**
	 * What access control checks to perform.
	 *
	 * @var Array of Strings
	 */
	private $_accessChecks = array(self::ACCESS_CHECK_IP);


	/**
	 * Allowed values for access control checks.
	 *
	 * @var Array of Strings
	 */
	private $_accessChecksValues = array(self::ACCESS_CHECK_IP,
												self::ACCESS_CHECK_FINGERPRINT
		);


	/**
	 * Fingerprints, defined by user for checks.
	 *
	 * @var Array of Strings
	 */
	private $_fingerprints;


    /**
     * Collection of commands and results
     *
     * @var Array of Objects
     */
    private $_collection = array();



    private $_languageConstructs = array('die', 'exit', 'echo');


    
	/**
	 * Contructor.
	 */
    private function __construct() {
		
	}

	/**
	 * Initializes an object, returns the instance.
	 *
	 * @param Bool $addDebugInfo
	 * @param Bool $displayFullTrace
	 * @param Bool $useBuffer
	 * @param String $dumpFunction
	 * @return Debug object
	 */
	public static function Call() {
		if (!self::$_Instance instanceof self) {
			self::$_Instance = new self();
		}

        return self::$_Instance;
	}


	/**
	 * Enables debugging.
	 */
	public static function Enable() {
        self::Call()->$_enabled = true;
	}


	/**
	 * Disables debugging.
	 */
	public static function Disable() {
		self::Call()->$_enabled = false;
	}


	/**
	 * Catches calls (for PHP version >= 5.3 only).
	 * Allows to call functions statically:
	 *		Debug::YourFunctionName(Arguments)
	 * All other PHP versions please use:
	 *		Debug::Call()->YourFunctionName(Arguments)
	 *
	 * @param String $name
	 * @param Array $arguments
	 */
	public function __callStatic($name, $arguments) {
		if (!$this->accessIsGranted()) {
			return false;
		}

		$exception = new Exception();

		return $this->_executeFunction($name, $arguments, $exception);
	}

	/**
	 * Catches calls. Example of usage:
	 *		Debug::Call()->YourFunctionName(Arguments)
	 *
	 * @param String $name
	 * @param Array $arguments
	 */
	public function __call($name, $arguments) {
		if (!$this->accessIsGranted()) {
			return false;
		}

		$exception = new Exception();

        return $this->_executeFunction($name, $arguments, $exception);
	}


	/**
	 * Sets parameters for access control. Example of usage:
	 *		Debug::SetAccessParam('IP', '206.190.60.37');
	 *
	 * @param String $key
	 * @param String $var
	 */
	public function setAccessParam($key, $var) {
		$this->_accessParams[$key] = $var;
	}


	/**
	 * Sets parameters for access control. Similar to <SetAccessParam>
	 *
	 * @param Associative Array of Strings $params
	 */
	public function setAccessParams(array $params) {
		$this->_accessParams = $params;
	}


	/**
	 * Gets a parameters. Similar to <GetAccessParam>.
	 *
	 * @return Associative Array of Strings
	 */
	public function getAccessParams() {
		return $this->_accessParams;
	}
    

    private function _logError($error) {
        if (empty($this->_errorLog)) {
            $this->_errorLog = array();
        }
        $this->_errorLog[] = $error;
    }


    private function _cleanErrorLog() {
        $this->_errorLog = null;
    }

    private function _getErrorLog() {
        return $this->_errorLog;
    }
    

    private function _getLastLoggedError() {
        return end($this->_errorLog);
    }
    

	/**
	 * Gets access parameters. 
	 *
	 * @param String $key
	 * @return String
	 */
	public function getAccessParam($key) {
        return isset($this->_accessParams[$key]) ? $this->_accessParams[$key] : null;
	}


	/**
	 * Performs function execution.
	 *
	 * @param String $name
	 * @param Associative Array $params
	 * @param Exception object $exception
	 */
	private function _executeFunction($name, $arguments, $exception) {
        $this->_cleanErrorLog();

        if ($this->_useBuffer) {
			ob_start();
		}

		$result = null;
		if ($this->_displayNone) {
			echo '<div style="display:none;">' . "\n";
		}
		
		if ($this->_addDebugInfo) {
			$trace = $exception->getTrace();
			$details = '';
			if ($this->_displayFullTrace) {
				$details = $exception->getTraceAsString();
			} else if (isset($trace[1])) {
				if (isset($trace[1]['file'])) {
					$details .= '	File: ' . $trace[1]['file'] . "\n";
				}

				if (isset($trace[1]['line'])) {
					$details .= '	Line: ' . $trace[1]['line'] . "\n";
				}
			}
			
			echo 'Function call details:' . "\n" .
				'	Function: ' . $name . "\n" .
				$details . 
				'	Arguments:' . "\n" .
				$this->_printFunctionArguments($arguments);

			echo "\n\n" . 'Call results the following output: ' . "\n";
		}		

		if (function_exists($name)) {
			$result = $name($arguments);
		} else if (in_array($name, $this->_languageConstructs)) {
            $result = $name($arguments);
        } else {
            $this->_logError('Function "' . $name . '" does not exist!');
            echo $this->_getLastLoggedError();
		}
		
		if ($this->_displayNone) {
			echo "\n" . '</div>';
		}

		if ($this->_useBuffer) {
			$this->_bufferData[] = ob_get_clean();
		}

        // Adding to collections.
        $this->_collection[] = new DebugCollection($name, $arguments, $result, $this->_getErrorLog(), $exception->getTrace());

		return $result;
	}


	/**
	 * Sets flag to use the buffer for debugging.
	 */
	public static function UseBuffer() {
		self::Call()->_useBuffer = true;
	}


	/**
	 * Unsets the flag to use the buffer for debugging.
	 */
	public static function NoBuffer() {
		self::Call()->_useBuffer = false;
	}


	/**
	 * Resets Debug information display configuration.
	 */
	public static function ResetDisplayConfiguration() {
		self::Call()->_addDebugInfo = self::ADD_DEBUG_INFO;
		self::Call()->_displayFullTrace = self::DISPLAY_FULL_TRACE;
		self::Call()->_useBuffer = self::USE_BUFFER;
	}


	/**
	 * Resets Debug access control parameters.
	 */
	public static function ResetAccessParams() {
		self::Call()->_accessParams = array();
	}


	/**
	 * Resets Debug access control parameters.
	 */
	public static function ResetCollection() {
		self::Call()->_collection = array();
	}


	/**
	 * Resets Debug dump function.
	 */
	public static function ResetDumpFunction() {
		self::Call()->_dumpFunction = self::DUMP_FUNCTION;
	}


	/**
	 * Global reset of the whole Debug object.
	 */
	public static function Reset() {
		self::ResetDisplayConfiguration();
		self::ResetAccessParams();
		self::EmptyBuffer();
		self::ResetFingerprints();
		self::ResetIps();
		self::NoBuffer();
        self::ResetCollection();
	}


	/**
	 * Resets <self::$_Ips> array of allowed IPs.
	 */
	public static function ResetIps() {
		self::Call()->_ips = array();
	}


	/**
	 * Empties the debug buffer.
	 */
	public static function EmptyBuffer() {
		self::Call()->_bufferData = array();
	}


	/**
	 * Returns debug buffer content.
	 *
	 * @param Bool $asString
	 * @return Array || String
	 */
	public static function GetBuffer($asString = false) {
		return ($asString) ? implode("\n", self::Call()->_bufferData) : self::Call()->_bufferData;
	}


	/**
	 * Prints out the function arguments in readable way.
	 *
	 * @param Array $arguments
	 * @return String
	 */
	private function _printFunctionArguments($arguments) {
		$dumpFunction = $this->_dumpFunction;
		$return = '';
		foreach ($arguments as $index => $argument) {
			$return .= 'Argument [' . $index . '] => ' .
				$dumpFunction($argument, true);
		}
		
		return $return;
	}


	/**
	 * Sets property <$_DumpFunction>.
	 *
	 * @param String $dumpFunction
	 */
	public static function SetDumpFunction($dumpFunction) {
		if (isset(self::Call()->_dumpFunctions[$dumpFunction])) {
			self::Call()->_dumpFunction = $dumpFunction;
		}
	}


	/**
	 * Sets property <$_AddDebugInfo>.
	 *
	 * @param Bool $addDebugInfo
	 * @return Debug object.
	 */
	public function showInfo($addDebugInfo = self::ADD_DEBUG_INFO) {
		$this->_addDebugInfo = $addDebugInfo;
		return $this;
	}


	/**
	 * Sets property <$_DisplayNone>.
	 *
	 * @param Bool $displayNone
	 * @return Debug object
	 */
	public function displayNone($displayNone = self::DISPLAY_NONE) {
		$this->_displayNone = $displayNone;
		return $this;
	}


	/**
	 * Sets property <$_UseBuffer>.
	 *
	 * @param Bool $bufferData
	 * @return Debug object.
	 */
	public function buffer($bufferData = self::USE_BUFFER) {
		$this->_useBuffer = $bufferData;
		return $this;
	}


	/**
	 * Sets property <$_DisplayFullTrace>.
	 *
	 * @param Bool $displayFullTrace
	 * @return Debug object
	 */
	public function trace($displayFullTrace = self::DISPLAY_FULL_TRACE) {
		$this->_displayFullTrace = $displayFullTrace;
		return $this;
	}


	/**
	 * Sets property <$_DumpFunction>.
	 *
	 * @param String $dumpFunction
	 * @return Debug object
	 */
	public function dump($dumpFunction = self::DUMP_FUNCTION) {
		self::SetDumpFunction($dumpFunction);
		return $this;
	}


	/**
	 * Sets value of property <$_DisplayNone>.
	 *
	 * @param Bool $displayNone
	 */
	public static function SetDisplayNone($displayNone = self::DISPLAY_NONE) {
		self::Call()->_displayNone = $displayNone;
	}


	/**
	 * Sets value of property <$_AddDebugInfo>.
	 *
	 * @param Bool $addDebugInfo
	 */
	public static function SetAddDebugInfo($addDebugInfo = self::ADD_DEBUG_INFO) {
		self::Call()->_addDebugInfo = $addDebugInfo;
	}


	/**
	 * Sets value of property <$_DisplayFullTrace>.
	 *
	 * @param <type> $displayFullTrace 
	 */
	public static function SetDisplayFullTrace($displayFullTrace = self::DISPLAY_FULL_TRACE) {
		self::Call()->_displayFullTrace = $displayFullTrace;
	}


	/**
	 * Adds an IP to check.
	 *
	 * @param String $ip
	 * @param Bool $access
	 */
	public static function AddIp($ip) {
		self::Call()->_ips[$ip] = $ip;
	}


	/**
	 * Adds a fingerprint to check.
	 *
	 * @param String $fingerprint
	 */
	public static function AddFingerprint($fingerprint) {
		self::Call()->_fingerprints[$fingerprint] = $fingerprint;
	}


	/**
	 * Resets the <self::$_Fingerprints> array.
	 */
	public static function ResetFingerprints() {
		self::Call()->_fingerprints = array();
	}
	

	/**
	 * Removes an IP from check.
	 *
	 * @param String $ip
	 */
	public static function RemoveIp($ip) {
		if (isset(self::Call()->_ips[$ip])) {
			self::Call()->_ips[$ip] = null; // Setting object to null
			unset(self::Call()->_ips[$ip]); // Unsetting the variable
		}
	}


	/**
	 * Gets an array of all IPs
	 *
	 * @return Array of DebugIpContainer objects
	 */
	public static function GetIps() {
		return self::Call()->_ips;
	}


	/**
	 * Peroforms the access control check. Returns true if one of the checks is
	 * successful.
	 *
	 * @return Bool
	 */
	public function accessIsGranted() {
		$result = false;
		foreach ($this->_accessChecks as $check) {
			$checkFunction = '_Perform' . ucfirst($check) . 'Check';
			if ($this->$checkFunction()) {
				$result = true;
			}
		}

		return $result;
	}


	/**
	 * Performs an IP check. Returns boolean true on success.
	 *
	 * @return Bool
	 */
	private static function _PerformIpCheck() {
		$currentIp = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : null;
		if (in_array($currentIp, array_keys(self::Call()->_ips))) {
			return true;
		} else {
			return false;
		}
	}


	/**
	 * Performs a fingerprint check. Returns boolean true on success.
	 *
	 * @return Bool
	 */
	private static function _PerformFingerprintCheck() {
		if (in_array(self::GenerateFingerprint(), self::Call()->_fingerprints)) {
			return true;
		} else {
			return false;
		}
	}


	/**
	 * Encodes a fingerprint.
	 *
	 * @return String
	 */
	public static function GenerateFingerprint() {
		return sha1(self::_GetFingerPrint());
	}


	/**
	 * Gets a fingerprint string based on <$_SERVER> data.
	 *
	 * @return String
	 */
	private static function _GetFingerprint() {
		$fingerprint = self::FINGERPRINT_PREFIX .
			(isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '') .
			(isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '') .
			(isset($_SERVER['HTTP_ACCEPT_ENCODING']) ? $_SERVER['HTTP_ACCEPT_ENCODING'] : '') .
			(isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? $_SERVER['HTTP_ACCEPT_LANGUAGE'] : '');
			
		return $fingerprint;
	}
	

	/**
	 * Adds an access control check.
	 *
	 * @param String $check 
	 */
	public static function AddAccessCheck($check) {
		if (in_array($check, self::Call()->_accessChecksValues)) {
			self::Call()->_accessChecks[$check] = $check;
		}
	}


	/**
	 * Unsets an access control check.
	 *
	 * @param String $check
	 */
	public static function RemoveAccessCheck($check) {
		if (in_array($check, self::Call()->_accessChecksValues)) {
			unset(self::Call()->_accessChecks[$check]);
		}
	}


    public function getCollection() {
        return $this->_collection;
    }
    
}



class DebugCollection {

    private $_function = null;

    private $_arguments = array();

    private $_return = null;

    private $_trace = null;

    private $_error = null;

    public function __construct($function, $arguments, $return, $error = null, $trace = null) {
        $this->_function    = $function;
        $this->_arguments   = $arguments;
        $this->_return      = $return;
        $this->_error       = $error;
        $this->_trace       = $trace;
    }

    public function getFunction() {
        return $this->_function;
    }

    public function getArguments($asString = false) {
        $asString = (bool)$asString;
        return ($asString) ? implode(', ', $this->_arguments) : $this->_arguments;
    }

    public function getReturn() {
        return $this->_return;
    }

    public function getTrace() {
        return $this->_trace;
    }
    
    public function getError() {
        return $this->_error;
    }
}
?>