Location: PHPKode > scripts > SVG Debug > svg-debug/svgdebug.php
<?

/**
* Width of the page used, in this case A4 size in centimetres
*/
define ("SIZEWIDTHCM",19);
/**
* Height of the page used, in this case A4 size in centimetres
*/
define ("SIZEHEIGHTCM",27);
/**
* Left Margin 
*/ 
define ("BEGINXSVG",10);
/**
* Top Margin 
*/ 
define ("BEGINYSVG",30);
/**
* Characters to be displayed in a line
*/ 
define ("MAXCHARACTERS",30);

/**
* Returns the microseconds since 0:00:00 January 1, 1970 GMT, 
*/
function getmicrotime()
{ 
	list($usec, $sec) = explode(" ",microtime()); 
	return ((float)$usec + (float)$sec); 
} 

/**
* This class is used to represent the information using the svf format
*/
class CSVGEngine
{
	/**
	* Width of the page
	*/
	var $m_nWidthSVG =SIZEWIDTHCM;
	/**
	* Height of the page
	*/
	var $m_nHeightSVG =SIZEHEIGHTCM;
	/**
	* Actual CoordX 
	*/
	var $m_nCoordXSVG =BEGINXSVG;
	/**
	* Actual CoordY 
	*/
	var $m_nCoordYSVG =BEGINYSVG;
	/**
	* The begining of the last row
	*/
	var $m_nCoordYSVGAnt;
	/**
	* Maximun size of the last row 
	*/
	var $m_nSpaceTotal =0;
	/**
	* Number of pages been generated
	*/	
	var $m_nPagesSVG =1;
	/**
	* File used to save the svg
	*/
	var $m_fileSVG;
	/**
	* Flag file ok
	*/
	var $m_bFileSVG;
	/**
	* Path of the directory for the svg files
	*/
	var $m_strDirectory ="";
	/**
	* Name of the file, the svgs will be saved using $m_strDirectory\\$m_strFile.$m_nPagesSVg.svg
	* example: c:\\temp\\test.1.svg
	*/
	var $m_strFile ="";
	
	/**
	* Constructor of the class
	*/
	function CSVGEngine($strDirectory,$strFile)
	{
		$this->m_strDirectory =$strDirectory;
		$this->m_strFile =$strFile;
		$this->m_nPagesSVG =1;
	}
	
	/**
	* This method will be invoked when a new svg file has to be created, for example when a page is full
	*/
	function OpenSVG()
	{
		// form the path of the new file
		$strPathTemp =sprintf("%s%s.%d.svg",$this->m_strDirectory,$this->m_strFile,$this->m_nPagesSVG);
		$this->m_fileSVG = @fopen($strPathTemp,"w");
		if ($this->m_fileSVG)
		{
			$this->m_bFileSVG =true;
			// Write the svg headers
			$this->HeaderSVG();
		}
		else
			$this->m_bFileSVG =false;		
		// Everything is okey?
		return $this->m_bFileSVG;
	}
	/**
	* Calculate if in the actual page is enough space, if not creates a new page after closing the actual page
	*/
	function IsSpaceYSVG($nDesplY)
	{
		// If we are very close to the end of the page, we close this page, and create a new one
		if (($this->m_nCoordYSVG + $nDesplY) > (0.95 *$this->m_nHeightSVG*100))
		{
			// close this pages
			$this->CloseSVG();
			// initialize all the auxiliar variables
			$this->m_nCoordYSVG = BEGINYSVG;
			$this->m_nCoordXSVG = BEGINXSVG;
			$this->m_nSpaceTotal =0.0;
			unset($this->m_nCoordYSVGAnt);
			$this->m_nPagesSVG = $this->m_nPagesSVG + 1;
			// create the new page
			$this->OpenSVG();
			// false, we have created a new page
			return false;
		}
		// ok,
		return true;
	}
	
	/**
	* Move the actual coordY to coordY + nDesplzY
	* if we are to close to the end of the page, close it and create a new one
	*/
	function MoveCoordYSVG($nDesplY)
	{
		if (($this->m_nCoordYSVG + $nDesplY) > (0.95 *$this->m_nHeightSVG*100))
		{
			$this->CloseSVG();
			$this->m_nCoordYSVG = BEGINYSVG;
			$this->m_nCoordXSVG = BEGINXSVG;
			$this->m_nSpaceTotal =0.0;
			unset($this->m_nCoordYSVGAnt);
			$this->m_nPagesSVG = $this->m_nPagesSVG + 1;
			$this->OpenSVG();
		}
		else
			$this->m_nCoordYSVG = $this->m_nCoordYSVG + $nDesplY;
	}
	
	/**
	* Write to the file the standard svg headers, if you want use another measure units
	* you have to change them here
	*/
	function HeaderSVG()
	{
		$strHeaderSVG ="<?xml version=\"1.0\" standalone=\"no\"?>";
		$strHeaderSVG .="<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" ";
		$strHeaderSVG .="\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">";
		
		$strTemp =sprintf("<svg width=\"%dcm\" height=\"%dcm\" viewBox=\"0 0 %d %d\" ",
					$this->m_nWidthSVG,$this->m_nHeightSVG,
					$this->m_nWidthSVG*100,$this->m_nHeightSVG*100);
		$strHeaderSVG .=$strTemp;
		$strHeaderSVG .="xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\">\n";
		
		if ($this->m_bFileSVG)
			fwrite($this->m_fileSVG,$strHeaderSVG);
	}
	
	/**
	* Write to the file the info about a new test
	* The parameters are the name of the test, and the time has begun
	*/
	function BeginTestSVG($strTest,$timeBegin)
	{
		$strTemp ="";
		$strBeginTest =sprintf("<text x=\"%d\" y=\"%d\" font-family=\"Monospace\" font-size=\"35\" fill=\"black\" text-anchor=\"start\">\n",
					$this->m_nCoordXSVG,$this->m_nCoordYSVG);
		$strTemp =sprintf("BEGIN %s AT %02d:%02d:%02d",$strTest,$timeBegin["hours"],$timeBegin["minutes"],$timeBegin["seconds"]);
		$strBeginTest .=$strTemp;
		$strBeginTest .="</text>\n";
		$this->MoveCoordYSVG(10);
		// Write to the file
		if ($this->m_bFileSVG)
		{
			fwrite($this->m_fileSVG,$strBeginTest);
			// Draw a line down the title
			$strTemp =sprintf("<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\"/>",0,$this->m_nCoordYSVG,$this->m_nWidthSVG*100,$this->m_nCoordYSVG);
			fwrite($this->m_fileSVG,$strTemp);
		}
		// Move to the next position
		$this->MoveCoordYSVG(30);
	}

	/**
	* Generate the code to write a new svg text
	*/
	function WriteTextSVG($strText)
	{
		$strTemp =sprintf("<text x=\"%d\" y=\"%d\" font-family=\"Monospace\" font-size=\"30\" fill=\"black\" text-anchor=\"start\">\n",
					$this->m_nCoordXSVG,$this->m_nCoordYSVG);
		$strTemp .=$strText;
		$strTemp .="</text>\n";
		return $strTemp;
	}
	
	/**
	* This is the main function, it draws the information about the variable been debugged
	* $strCode -> title of the step
	* $strNameObj -> name of the object
	* $strClass -> name of the class of the object
	* $dSecs -> seconds since the last call to debug
	*/
	function WriteDebugSVG($strCode,$strNameObj,$strClass,$arrVars,$dSecs)
	{
		// Vertical distance between the lines
		$nSpaceVar=30;
		if (is_array($arrVars))
			$nCount =count($arrVars);
		else
			$nCount =0;
		// if we are too close to the right, we get down to the next line
		if ($this->m_nCoordXSVG > (80*$this->m_nWidthSVG))
		{
			$this->m_nCoordXSVG =BEGINXSVG;
			$this->m_nCoordYSVG =$this->m_nCoordYSVGAnt;
			$this->MoveCoordYSVG($this->m_nSpaceTotal+$nSpaceVar);
			$this->m_nSpaceTotal =0;
			unset($this->m_nCoordYSVGAnt);
		}
		// calculate the vertical space we need to draw all the information
		$nSpaceTotal =($nCount + 3) *($nSpaceVar);
		// if this space is the biggest we keep it
		if ($this->m_nSpaceTotal < $nSpaceTotal)
		{
			// if the space is too big, we create a new page
			$this->IsSpaceYSVG($nSpaceTotal);
			// we keep the new value
			$this->m_nSpaceTotal =$nSpaceTotal;
		}
		
		// if this is not the first column, we recover the begining position y
		// for this row
		if (isset($this->m_nCoordYSVGAnt))
			$this->m_nCoordYSVG =$this->m_nCoordYSVGAnt;
		else
			$this->m_nCoordYSVGAnt=$this->m_nCoordYSVG;

		// we write the name of the step and the seconds since the last call to debug
		$strSecs = sprintf("%.6f",$dSecs);
		$strTemp =$this->WriteTextSVG($strCode ."(". $strSecs .")");
		$this->MoveCoordYSVG($nSpaceVar);
		$strTemp .=$this->WriteTextSVG($strNameObj ."(" .$strClass .")");
		$this->MoveCoordYSVG($nSpaceVar+10);
		
		// if we have information about the variables of the object, we write the info
		if (is_array($arrVars))
		{
			$nMaxStrlen =0;
			reset($arrVars);
			while (list($strVar, $strValue) = each($arrVars))
			{
				$strVarValue =$strVar ." : ". $strValue;
				if (strlen($strVarValue) > MAXCHARACTERS)
					$strVarValue =substr($strVarValue,0,MAXCHARACTERS) . "...";
				$strTemp .=$this->WriteTextSVG($strVarValue);
				$this->MoveCoordYSVG($nSpaceVar);
				if (strlen($strVarValue) > $nMaxStrlen)
					$nMaxStrlen =strlen($strVarValue);
			}
		}
		
		// the page will be divided into three columns
		$this->m_nCoordXSVG = $this->m_nCoordXSVG + 0.33 * $this->m_nWidthSVG*100;
		// if we have a valid file, we write the information
		if ($this->m_bFileSVG)
			fwrite($this->m_fileSVG,$strTemp);
	}
			
	/**
	* The test is finished, we write the information and the time
	*/
	function EndTestSVG($strTest,$timeClose)
	{
		$this->m_nCoordXSVG =BEGINXSVG;
		//$this->MoveCoordYSVG(20);
		if ($this->m_bFileSVG)
		{
			$strTemp =sprintf("<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\"/>",0,$this->m_nCoordYSVG,$this->m_nWidthSVG*100,$this->m_nCoordYSVG);
			fwrite($this->m_fileSVG,$strTemp);			
		}
		$this->MoveCoordYSVG(30);
		$strTemp ="";
		$strCloseTest =sprintf("<text x=\"%d\" y=\"%d\" font-family=\"Monospace\" font-size=\"35\" fill=\"black\" text-anchor=\"start\">\n",
					$this->m_nCoordXSVG,$this->m_nCoordYSVG);
		$strTemp =sprintf("CLOSE %s AT %02d:%02d:%02d",$strTest,$timeClose["hours"],$timeClose["minutes"],$timeClose["seconds"]);
		$strCloseTest .=$strTemp;
		$strCloseTest .="</text>\n";
		if ($this->m_bFileSVG)
		{
			fwrite($this->m_fileSVG,$strCloseTest);
		}
	}
	
	/**
	* Close the actual svg file, and write the last of svg end
	*/
	function CloseSVG()
	{
		if ($this->m_bFileSVG)
		{
			fwrite($this->m_fileSVG,"</svg>");
			fclose($this->m_fileSVG);			
		}
	}

	/**
	* To navigate easily we generate a html file which open the svg, 
	* and write links to the prev and to next files
	*/
	function GenHtmlFiles()
	{
		for ($i=1;$i<=$this->m_nPagesSVG;$i++)
		{
			$strTemp ="";
			$strPathTemp ="";
			$strPathTemp =sprintf("%s%s.%d.html",$this->m_strDirectory,$this->m_strFile,$i);
			$fileHTML = @fopen($strPathTemp,"w");
			if (!$fileHTML)
				return;
			$strTemp ="<html><head><title>CONTENTS</title>\n";
			fwrite($fileHTML,$strTemp);
			$strTemp =sprintf("</head><body><embed src=\"%s.%d.svg\" style=\"width: %dcm; height: %dcm\">\n",
				$this->m_strFile,$i,$this->m_nWidthSVG,$this->m_nHeightSVG);
			fwrite($fileHTML,$strTemp);
			
			if ($this->m_nPagesSVG != 1)
			{
				$strTemp ="<p align=\"center\"><i><b>\n";
				fwrite($fileHTML,$strTemp);
			
				if ($i > 1)
				{
					$strTemp =sprintf("<a href=\"%s.%d.html\"><FONT face=\"Courier New\" size=2>Prev</font></a>&nbsp;\n",
							$this->m_strFile,$i-1);
					fwrite($fileHTML,$strTemp);
				}
			
				if ($i < $this->m_nPagesSVG)
				{
					$strTemp =sprintf("<a href=\"%s.%d.html\"><FONT face=\"Courier New\" size=2>Next</font></a>\n",
							$this->m_strFile,$i+1);
					fwrite($fileHTML,$strTemp);
				}
			
				if ($this->m_nPagesSVG != 1)
				{	
					$strTemp ="</i></b></p>\n";
					fwrite($fileHTML,$strTemp);
				}
			}
			$strTemp ="</body></html>\n";
			fwrite($fileHTML,$strTemp);
		}		
	}
}

/**
* Main class for the user
*/
class CSVGDebug
{
	/**
	* Path to directory used to save the file
	*/
	var $m_strDirectory;
	/**
	* Name of the test
	*/
	var $m_strTest;
	/**
	* Time begining the test
	*/
	var $m_dateBegin;
	/**
	* Time of the debug event
	*/
	var $m_timeDebug;
	/**
	* Time finishing the test
	*/
	var $m_dateClose;
	/**
	* SVG Engine to generate the svg files
	*/
	var $m_SVGEngine;
	
	/**
	* Constructor of the class, save the information and creates the svg engine
	*/
	function CSVGDebug($strDirectory,$strTest)
	{
		$this->m_strDirectory =$strDirectory;
		if ($strTest == "")
			$strTest ="test";
		$this->m_strTest =$strTest;
		$this->m_SVGEngine = new CSVGEngine($this->m_strDirectory,$this->m_strTest);
	}
	
	/**
	* Begining of the test
	*/
	function Open()
	{
		$this->m_dateBegin =getdate();
		$this->m_timeDebug =getmicrotime();
		// Open the svg file, if everything is ok, generate the svg begining
		if ($this->m_SVGEngine->OpenSVG())
		{
			$this->m_SVGEngine->BeginTestSVG($this->m_strTest,$this->m_dateBegin);
		}
	}

	/**
	* Save the information about the variable
	*/
	function Debug($obj,$strCode)
	{
		$timeNow=getmicrotime();
		$dSecs =$timeNow - $this->m_timeDebug;
		$this->m_timeDebug =$timeNow;
		$strClassName =get_class($obj);
		// if the object is really an object
		if (gettype($obj) == "object")
		{
			// we look if there a special way to evaluate this class
			// if the class of the object is Test, the method has to be "EvalTest"
			$strEvalClass ="Eval".$strClassName;
			if (method_exists($this,$strEvalClass))
			{
				// For every variable of the object, we validate if we have to show it
				$arrVars =get_object_vars($obj);
				$arrNewVars = array();
				reset($arrVars);
				while (list($strVar, $strValue) = each($arrVars))
				{
					if ($this->$strEvalClass($strVar))
					{
						$arrNewVars[$strVar] =$strValue;
					}
				}
				// we write the specific information for this class
				$this->m_SVGEngine->WriteDebugSVG($strCode,$obj,get_class($obj),$arrNewVars,$dSecs);
			}
			else
				// we write all the information of the class
				$this->m_SVGEngine->WriteDebugSVG($strCode,$obj,get_class($obj),get_object_vars($obj),$dSecs);
		}
		else
		{
			// the object is not an object, we only write its value
			$arrVars = array();
			$arrVars["value"] =$obj;
			$this->m_SVGEngine->WriteDebugSVG($strCode,$obj,gettype($obj),$arrVars,$dSecs);
		}
	}
	
	/**
	* Specific class information, for the class CSVGEngine we only want to show the value of the variable "m_strDirectory"
	*/
	function EvalCSVGEngine($strVar)
	{
		if ($strVar == "m_strDirectory")
			return true;
		if ($strVar == "m_fileSVG")
			return true;
		if ($strVar == "m_nPagesSVG")
			return true;
		return false;
	}
	
	/**
	* Close the actual test
	*/
	function Close()
	{
		$this->m_timeClose =getdate();
		$this->m_SVGEngine->EndTestSVG($this->m_strTest,$this->m_timeClose);
		$this->m_SVGEngine->CloseSVG();			
		$this->m_SVGEngine->GenHtmlFiles();
	}
}

?>
Return current item: SVG Debug